@praxisui/cron-builder 9.0.0-beta.85 → 9.0.0-beta.88
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": "1.0.0",
|
|
3
|
-
"generatedAt": "2026-07-
|
|
3
|
+
"generatedAt": "2026-07-23T02:50:28.389Z",
|
|
4
4
|
"packageName": "@praxisui/cron-builder",
|
|
5
|
-
"packageVersion": "9.0.0-beta.
|
|
5
|
+
"packageVersion": "9.0.0-beta.88",
|
|
6
6
|
"sourceRegistry": "praxis-component-registry-ingestion",
|
|
7
7
|
"sourceRegistryVersion": "1.0.0",
|
|
8
8
|
"componentCount": 1,
|
|
@@ -1553,6 +1553,66 @@
|
|
|
1553
1553
|
{
|
|
1554
1554
|
"chunkIndex": 3,
|
|
1555
1555
|
"chunkKind": "authoring_manifest",
|
|
1556
|
+
"content": "{\"operationId\":\"cron.expression.set\",\"schemaVersion\":\"1.0.0\",\"manifestVersion\":\"1.0.0\",\"componentId\":\"pdx-cron-builder\",\"ownerPackage\":\"@praxisui/cron-builder\",\"configSchemaId\":\"CronBuilderMetadata\",\"chunkSection\":\"operation_card\",\"semanticSummary\":\"Set CRON expression Effects: compile-domain-patch. Use cron expression 0 8 * * 1-5. Use cron expression 99 99 * * *.\",\"scope\":\"global\",\"target\":{\"kind\":\"expression\",\"resolver\":\"schedule-expression\",\"required\":false},\"inputContract\":{\"required\":[\"cron\"],\"properties\":[\"cron\",\"dialect\",\"seconds\"],\"semanticTerms\":[\"cron\",\"dialect\",\"seconds\",\"unix\",\"quartz\",\"aws-eventbridge\",\"kubernetes\",\"github-actions\",\"gcp-scheduler\"]},\"effects\":[\"compile-domain-patch\"],\"affectedPaths\":[\"schedule.kind\",\"schedule.expression\",\"schedule.expression.cron\",\"schedule.expression.dialect\",\"schedule.expression.seconds\",\"value\",\"diagnostics\"],\"validators\":[{\"validatorId\":\"cron-expression-valid\",\"level\":\"error\",\"code\":\"PCRON001\",\"description\":\"CRON expressions must pass the canonical cron-runtime parser for the selected dialect before schedule/value paths are patched.\"},{\"validatorId\":\"cron-dialect-compatible\",\"level\":\"error\",\"code\":\"PCRON002\",\"description\":\"Field count, seconds support and dialect-specific rules must match CRON_DIALECTS.\"},{\"validatorId\":\"editor-runtime-round-trip\",\"level\":\"error\",\"code\":\"PCRON010\",\"description\":\"ControlValueAccessor, runtime preview and AI adapter snapshots must preserve expression and timezone.\"}],\"preconditions\":[\"config-initialized\"],\"submissionImpact\":\"affects-submission\",\"presentationAffordances\":[],\"positiveExamples\":[{\"id\":\"set-explicit-expression\",\"request\":\"Use cron expression 0 8 * * 1-5.\",\"operationId\":\"cron.expression.set\",\"params\":{\"cron\":\"0 8 * * 1-5\",\"dialect\":\"unix\",\"seconds\":false},\"isPositive\":true}],\"negativeExamples\":[{\"id\":\"reject-impossible-expression\",\"request\":\"Use cron expression 99 99 * * *.\",\"operationId\":\"cron.expression.set\",\"params\":{\"cron\":\"99 99 * * *\",\"dialect\":\"unix\"},\"isPositive\":false}]}",
|
|
1557
|
+
"sourcePointer": "projects/praxis-cron-builder/src/lib/ai/praxis-cron-builder-authoring-manifest.ts",
|
|
1558
|
+
"contentHash": "deb8ae9423f4e58f8350b8de7f10c4f6997ef5c88a72f1e14c5124ab502b4afb",
|
|
1559
|
+
"sourceKind": "component_definition",
|
|
1560
|
+
"sourceId": "pdx-cron-builder",
|
|
1561
|
+
"corpusVersion": "1.0.0"
|
|
1562
|
+
},
|
|
1563
|
+
{
|
|
1564
|
+
"chunkIndex": 4,
|
|
1565
|
+
"chunkKind": "authoring_manifest",
|
|
1566
|
+
"content": "{\"operationId\":\"cron.frequency.set\",\"schemaVersion\":\"1.0.0\",\"manifestVersion\":\"1.0.0\",\"componentId\":\"pdx-cron-builder\",\"ownerPackage\":\"@praxisui/cron-builder\",\"configSchemaId\":\"CronBuilderMetadata\",\"chunkSection\":\"operation_card\",\"semanticSummary\":\"Set schedule frequency Effects: compile-domain-patch. Run every weekday at 08:00. Run every 15 minutes. Run monthly on the first day at 09:00.\",\"scope\":\"global\",\"target\":{\"kind\":\"frequency\",\"resolver\":\"schedule-kind-and-recurrence\",\"required\":false},\"inputContract\":{\"required\":[\"kind\",\"recurrence\"],\"properties\":[\"kind\",\"recurrence\",\"dialect\"],\"semanticTerms\":[\"kind\",\"recurrence\",\"dialect\",\"once\",\"interval\",\"daily\",\"weekly\",\"monthly\",\"customCron\",\"unix\",\"quartz\",\"aws-eventbridge\",\"kubernetes\",\"github-actions\",\"gcp-scheduler\"]},\"effects\":[\"compile-domain-patch\"],\"affectedPaths\":[\"schedule.kind\",\"schedule.recurrence\",\"schedule.expression\",\"value\"],\"validators\":[{\"validatorId\":\"frequency-maps-to-canonical-expression\",\"level\":\"error\",\"code\":\"PCRON004\",\"description\":\"Structured frequency intent must compile through compileScheduleExpression into the canonical expression when portable.\"},{\"validatorId\":\"cron-expression-valid\",\"level\":\"error\",\"code\":\"PCRON001\",\"description\":\"CRON expressions must pass the canonical cron-runtime parser for the selected dialect before schedule/value paths are patched.\"},{\"validatorId\":\"diagnostics-before-patch\",\"level\":\"error\",\"code\":\"PCRON009\",\"description\":\"Operations that compile recurrence or presets must evaluate diagnostics before mutating canonical schedule/value paths.\"}],\"preconditions\":[\"config-initialized\"],\"submissionImpact\":\"affects-submission\",\"presentationAffordances\":[],\"positiveExamples\":[{\"id\":\"weekday-0800\",\"request\":\"Run every weekday at 08:00.\",\"operationId\":\"cron.frequency.set\",\"params\":{\"kind\":\"daily\",\"recurrence\":{\"daily\":{\"times\":[\"08:00\"],\"onlyWeekdays\":true}},\"dialect\":\"unix\"},\"isPositive\":true},{\"id\":\"every-15-minutes\",\"request\":\"Run every 15 minutes.\",\"operationId\":\"cron.frequency.set\",\"params\":{\"kind\":\"interval\",\"recurrence\":{\"interval\":{\"every\":15,\"unit\":\"minutes\"}},\"dialect\":\"unix\"},\"isPositive\":true},{\"id\":\"monthly-first-day\",\"request\":\"Run monthly on the first day at 09:00.\",\"operationId\":\"cron.frequency.set\",\"params\":{\"kind\":\"monthly\",\"recurrence\":{\"monthly\":{\"mode\":\"dayOfMonth\",\"dayOfMonth\":1,\"times\":[\"09:00\"]}},\"dialect\":\"unix\"},\"isPositive\":true}],\"negativeExamples\":[]}",
|
|
1567
|
+
"sourcePointer": "projects/praxis-cron-builder/src/lib/ai/praxis-cron-builder-authoring-manifest.ts",
|
|
1568
|
+
"contentHash": "fc097a8ebf4717ddad21c245c3b2c53d6dd10ad62b2bf3043361cbdd9b3f756e",
|
|
1569
|
+
"sourceKind": "component_definition",
|
|
1570
|
+
"sourceId": "pdx-cron-builder",
|
|
1571
|
+
"corpusVersion": "1.0.0"
|
|
1572
|
+
},
|
|
1573
|
+
{
|
|
1574
|
+
"chunkIndex": 5,
|
|
1575
|
+
"chunkKind": "authoring_manifest",
|
|
1576
|
+
"content": "{\"operationId\":\"cron.timezone.set\",\"schemaVersion\":\"1.0.0\",\"manifestVersion\":\"1.0.0\",\"componentId\":\"pdx-cron-builder\",\"ownerPackage\":\"@praxisui/cron-builder\",\"configSchemaId\":\"CronBuilderMetadata\",\"chunkSection\":\"operation_card\",\"semanticSummary\":\"Set schedule timezone Effects: compile-domain-patch. Change timezone to America/Sao_Paulo and preview the next runs. Change timezone to Mars/Olympus.\",\"scope\":\"global\",\"target\":{\"kind\":\"timezone\",\"resolver\":\"schedule-timezone\",\"required\":false},\"inputContract\":{\"required\":[\"timezone\"],\"properties\":[\"timezone\"],\"semanticTerms\":[\"timezone\"]},\"effects\":[\"compile-domain-patch\"],\"affectedPaths\":[\"schedule.timezone\",\"metadata.timezone\",\"preview\",\"diagnostics\"],\"validators\":[{\"validatorId\":\"timezone-valid\",\"level\":\"error\",\"code\":\"PCRON003\",\"description\":\"Timezone must be a valid IANA timezone accepted by Intl.DateTimeFormat and schedule preview.\"},{\"validatorId\":\"preview-matches-expression\",\"level\":\"error\",\"code\":\"PCRON007\",\"description\":\"Preview occurrences must be generated from the same expression, timezone and from-date requested by authoring.\"},{\"validatorId\":\"editor-runtime-round-trip\",\"level\":\"error\",\"code\":\"PCRON010\",\"description\":\"ControlValueAccessor, runtime preview and AI adapter snapshots must preserve expression and timezone.\"}],\"preconditions\":[\"config-initialized\"],\"submissionImpact\":\"affects-submission\",\"presentationAffordances\":[],\"positiveExamples\":[{\"id\":\"change-timezone-preview\",\"request\":\"Change timezone to America/Sao_Paulo and preview the next runs.\",\"operationId\":\"cron.timezone.set\",\"params\":{\"timezone\":\"America/Sao_Paulo\"},\"isPositive\":true}],\"negativeExamples\":[{\"id\":\"reject-invalid-timezone\",\"request\":\"Change timezone to Mars/Olympus.\",\"operationId\":\"cron.timezone.set\",\"params\":{\"timezone\":\"Mars/Olympus\"},\"isPositive\":false}]}",
|
|
1577
|
+
"sourcePointer": "projects/praxis-cron-builder/src/lib/ai/praxis-cron-builder-authoring-manifest.ts",
|
|
1578
|
+
"contentHash": "98dadf3ee7b00bdb8f756716d99ceda86b1450ab917935e3add9cdcefdb52e34",
|
|
1579
|
+
"sourceKind": "component_definition",
|
|
1580
|
+
"sourceId": "pdx-cron-builder",
|
|
1581
|
+
"corpusVersion": "1.0.0"
|
|
1582
|
+
},
|
|
1583
|
+
{
|
|
1584
|
+
"chunkIndex": 6,
|
|
1585
|
+
"chunkKind": "authoring_manifest",
|
|
1586
|
+
"content": "{\"operationId\":\"cron.preset.apply\",\"schemaVersion\":\"1.0.0\",\"manifestVersion\":\"1.0.0\",\"componentId\":\"pdx-cron-builder\",\"ownerPackage\":\"@praxisui/cron-builder\",\"configSchemaId\":\"CronBuilderMetadata\",\"chunkSection\":\"operation_card\",\"semanticSummary\":\"Apply CRON preset Effects: compile-domain-patch. Apply the business hours preset.\",\"scope\":\"meta\",\"target\":{\"kind\":\"preset\",\"resolver\":\"cron-preset-by-label-or-expression\",\"required\":true},\"inputContract\":{\"required\":[\"labelOrCron\"],\"properties\":[\"labelOrCron\",\"timezone\"],\"semanticTerms\":[\"labelOrCron\",\"timezone\"]},\"effects\":[\"compile-domain-patch\"],\"affectedPaths\":[\"schedule.kind\",\"schedule.expression\",\"schedule.timezone\",\"value\"],\"validators\":[{\"validatorId\":\"preset-exists\",\"level\":\"error\",\"code\":\"PCRON005\",\"description\":\"Preset operations must resolve an existing preset by label or cron expression.\"},{\"validatorId\":\"preset-maps-to-canonical-expression\",\"level\":\"error\",\"code\":\"PCRON006\",\"description\":\"Preset cron values must normalize into ScheduleAuthoringConfig and a valid canonical expression.\"},{\"validatorId\":\"cron-expression-valid\",\"level\":\"error\",\"code\":\"PCRON001\",\"description\":\"CRON expressions must pass the canonical cron-runtime parser for the selected dialect before schedule/value paths are patched.\"}],\"preconditions\":[\"config-initialized\",\"target-preset-exists\"],\"submissionImpact\":\"affects-submission\",\"presentationAffordances\":[],\"positiveExamples\":[{\"id\":\"apply-business-hours-preset\",\"request\":\"Apply the business hours preset.\",\"operationId\":\"cron.preset.apply\",\"target\":\"business hours\",\"params\":{\"labelOrCron\":\"business hours\"},\"isPositive\":true}],\"negativeExamples\":[]}",
|
|
1587
|
+
"sourcePointer": "projects/praxis-cron-builder/src/lib/ai/praxis-cron-builder-authoring-manifest.ts",
|
|
1588
|
+
"contentHash": "e4ce1fe13fbe0fb8824b367732a2fc200fe9119e774279de546985de9900b6c2",
|
|
1589
|
+
"sourceKind": "component_definition",
|
|
1590
|
+
"sourceId": "pdx-cron-builder",
|
|
1591
|
+
"corpusVersion": "1.0.0"
|
|
1592
|
+
},
|
|
1593
|
+
{
|
|
1594
|
+
"chunkIndex": 7,
|
|
1595
|
+
"chunkKind": "authoring_manifest",
|
|
1596
|
+
"content": "{\"operationId\":\"cron.validate\",\"schemaVersion\":\"1.0.0\",\"manifestVersion\":\"1.0.0\",\"componentId\":\"pdx-cron-builder\",\"ownerPackage\":\"@praxisui/cron-builder\",\"configSchemaId\":\"CronBuilderMetadata\",\"chunkSection\":\"operation_card\",\"semanticSummary\":\"Validate schedule Effects: compile-domain-patch. Validate 99 99 * * * and explain why it is invalid.\",\"scope\":\"global\",\"target\":{\"kind\":\"validation\",\"resolver\":\"schedule-validation-request\",\"required\":false},\"inputContract\":{\"required\":[],\"properties\":[\"cron\",\"schedule\",\"timezone\",\"dialect\"],\"semanticTerms\":[\"cron\",\"schedule\",\"timezone\",\"dialect\",\"unix\",\"quartz\",\"aws-eventbridge\",\"kubernetes\",\"github-actions\",\"gcp-scheduler\"]},\"effects\":[\"compile-domain-patch\"],\"affectedPaths\":[\"diagnostics\"],\"validators\":[{\"validatorId\":\"invalid-schedules-return-diagnostics\",\"level\":\"error\",\"code\":\"PCRON008\",\"description\":\"Validation and preview requests for invalid schedules must return diagnostics and must not patch schedule/value fields.\"},{\"validatorId\":\"cron-expression-valid\",\"level\":\"error\",\"code\":\"PCRON001\",\"description\":\"CRON expressions must pass the canonical cron-runtime parser for the selected dialect before schedule/value paths are patched.\"},{\"validatorId\":\"timezone-valid\",\"level\":\"error\",\"code\":\"PCRON003\",\"description\":\"Timezone must be a valid IANA timezone accepted by Intl.DateTimeFormat and schedule preview.\"}],\"preconditions\":[\"config-initialized\"],\"submissionImpact\":\"none\",\"presentationAffordances\":[],\"positiveExamples\":[{\"id\":\"diagnose-invalid-expression\",\"request\":\"Validate 99 99 * * * and explain why it is invalid.\",\"operationId\":\"cron.validate\",\"params\":{\"cron\":\"99 99 * * *\",\"dialect\":\"unix\"},\"isPositive\":true}],\"negativeExamples\":[]}",
|
|
1597
|
+
"sourcePointer": "projects/praxis-cron-builder/src/lib/ai/praxis-cron-builder-authoring-manifest.ts",
|
|
1598
|
+
"contentHash": "5b8b10c965f8ec9092e1169bff54c3cbf5540dd655ae8c6b9056e0ad4bfc3e7a",
|
|
1599
|
+
"sourceKind": "component_definition",
|
|
1600
|
+
"sourceId": "pdx-cron-builder",
|
|
1601
|
+
"corpusVersion": "1.0.0"
|
|
1602
|
+
},
|
|
1603
|
+
{
|
|
1604
|
+
"chunkIndex": 8,
|
|
1605
|
+
"chunkKind": "authoring_manifest",
|
|
1606
|
+
"content": "{\"operationId\":\"cron.preview.generate\",\"schemaVersion\":\"1.0.0\",\"manifestVersion\":\"1.0.0\",\"componentId\":\"pdx-cron-builder\",\"ownerPackage\":\"@praxisui/cron-builder\",\"configSchemaId\":\"CronBuilderMetadata\",\"chunkSection\":\"operation_card\",\"semanticSummary\":\"Generate schedule preview Effects: compile-domain-patch. Preview the next five runs from 2026-04-20T00:00:00Z.\",\"scope\":\"global\",\"target\":{\"kind\":\"preview\",\"resolver\":\"schedule-preview-config\",\"required\":false},\"inputContract\":{\"required\":[],\"properties\":[\"occurrences\",\"from\",\"timezone\",\"locale\"],\"semanticTerms\":[\"occurrences\",\"from\",\"timezone\",\"locale\"]},\"effects\":[\"compile-domain-patch\"],\"affectedPaths\":[\"preview\",\"diagnostics\"],\"validators\":[{\"validatorId\":\"preview-matches-expression\",\"level\":\"error\",\"code\":\"PCRON007\",\"description\":\"Preview occurrences must be generated from the same expression, timezone and from-date requested by authoring.\"},{\"validatorId\":\"timezone-valid\",\"level\":\"error\",\"code\":\"PCRON003\",\"description\":\"Timezone must be a valid IANA timezone accepted by Intl.DateTimeFormat and schedule preview.\"},{\"validatorId\":\"invalid-schedules-return-diagnostics\",\"level\":\"error\",\"code\":\"PCRON008\",\"description\":\"Validation and preview requests for invalid schedules must return diagnostics and must not patch schedule/value fields.\"}],\"preconditions\":[\"config-initialized\"],\"submissionImpact\":\"none\",\"presentationAffordances\":[],\"positiveExamples\":[{\"id\":\"preview-next-five\",\"request\":\"Preview the next five runs from 2026-04-20T00:00:00Z.\",\"operationId\":\"cron.preview.generate\",\"params\":{\"occurrences\":5,\"from\":\"2026-04-20T00:00:00.000Z\",\"timezone\":\"UTC\"},\"isPositive\":true}],\"negativeExamples\":[]}",
|
|
1607
|
+
"sourcePointer": "projects/praxis-cron-builder/src/lib/ai/praxis-cron-builder-authoring-manifest.ts",
|
|
1608
|
+
"contentHash": "686fa9e5260525ec9a5d7b2aa41cc7e623cebd7e7a691b079eaadbb0200b3cd2",
|
|
1609
|
+
"sourceKind": "component_definition",
|
|
1610
|
+
"sourceId": "pdx-cron-builder",
|
|
1611
|
+
"corpusVersion": "1.0.0"
|
|
1612
|
+
},
|
|
1613
|
+
{
|
|
1614
|
+
"chunkIndex": 9,
|
|
1615
|
+
"chunkKind": "authoring_manifest",
|
|
1556
1616
|
"content": "{\"schemaVersion\":\"1.0.0\",\"manifestVersion\":\"1.0.0\",\"componentId\":\"pdx-cron-builder\",\"ownerPackage\":\"@praxisui/cron-builder\",\"configSchemaId\":\"CronBuilderMetadata\",\"chunkSection\":\"identity\"}",
|
|
1557
1617
|
"sourcePointer": "projects/praxis-cron-builder/src/lib/ai/praxis-cron-builder-authoring-manifest.ts",
|
|
1558
1618
|
"contentHash": "1cceaf90502599b642b54b358b030a6dc7d00034a78f382731db98bb7be25633",
|
|
@@ -1561,7 +1621,7 @@
|
|
|
1561
1621
|
"corpusVersion": "1.0.0"
|
|
1562
1622
|
},
|
|
1563
1623
|
{
|
|
1564
|
-
"chunkIndex":
|
|
1624
|
+
"chunkIndex": 10,
|
|
1565
1625
|
"chunkKind": "authoring_manifest",
|
|
1566
1626
|
"content": "{\"schemaVersion\":\"1.0.0\",\"manifestVersion\":\"1.0.0\",\"componentId\":\"pdx-cron-builder\",\"ownerPackage\":\"@praxisui/cron-builder\",\"configSchemaId\":\"CronBuilderMetadata\",\"chunkSection\":\"runtimeInputs\",\"runtimeInputs\":[{\"name\":\"metadata\",\"type\":\"CronBuilderMetadata\",\"description\":\"Builder UI, timezone, locale, presets, validation and preview configuration.\"},{\"name\":\"value\",\"type\":\"string | ScheduleAuthoringConfig\",\"description\":\"Current CRON string compatibility value or canonical schedule authoring config.\"},{\"name\":\"disabled\",\"type\":\"boolean\",\"description\":\"ControlValueAccessor disabled state.\"}]}",
|
|
1567
1627
|
"sourcePointer": "projects/praxis-cron-builder/src/lib/ai/praxis-cron-builder-authoring-manifest.ts",
|
|
@@ -1571,7 +1631,7 @@
|
|
|
1571
1631
|
"corpusVersion": "1.0.0"
|
|
1572
1632
|
},
|
|
1573
1633
|
{
|
|
1574
|
-
"chunkIndex":
|
|
1634
|
+
"chunkIndex": 11,
|
|
1575
1635
|
"chunkKind": "authoring_manifest",
|
|
1576
1636
|
"content": "{\"schemaVersion\":\"1.0.0\",\"manifestVersion\":\"1.0.0\",\"componentId\":\"pdx-cron-builder\",\"ownerPackage\":\"@praxisui/cron-builder\",\"configSchemaId\":\"CronBuilderMetadata\",\"chunkSection\":\"editableTargets\",\"editableTargets\":[{\"kind\":\"expression\",\"resolver\":\"schedule-expression\",\"description\":\"Canonical CRON expression under schedule.expression or legacy value.\"},{\"kind\":\"frequency\",\"resolver\":\"schedule-kind-and-recurrence\",\"description\":\"Business recurrence intent compiled into a canonical expression.\"},{\"kind\":\"timezone\",\"resolver\":\"schedule-timezone\",\"description\":\"IANA timezone used for preview and schedule metadata.\"},{\"kind\":\"preview\",\"resolver\":\"schedule-preview-config\",\"description\":\"Read-only preview generation request for next occurrences.\"},{\"kind\":\"validation\",\"resolver\":\"schedule-validation-request\",\"description\":\"Read-only validation diagnostics request for expression or schedule config.\"},{\"kind\":\"preset\",\"resolver\":\"cron-preset-by-label-or-expression\",\"description\":\"Preset entry in metadata.presets[] or top-level presets[].\"}]}",
|
|
1577
1637
|
"sourcePointer": "projects/praxis-cron-builder/src/lib/ai/praxis-cron-builder-authoring-manifest.ts",
|
|
@@ -1581,7 +1641,7 @@
|
|
|
1581
1641
|
"corpusVersion": "1.0.0"
|
|
1582
1642
|
},
|
|
1583
1643
|
{
|
|
1584
|
-
"chunkIndex":
|
|
1644
|
+
"chunkIndex": 12,
|
|
1585
1645
|
"chunkKind": "authoring_manifest",
|
|
1586
1646
|
"content": "{\"schemaVersion\":\"1.0.0\",\"manifestVersion\":\"1.0.0\",\"componentId\":\"pdx-cron-builder\",\"ownerPackage\":\"@praxisui/cron-builder\",\"configSchemaId\":\"CronBuilderMetadata\",\"chunkSection\":\"operations\",\"operations\":[{\"operationId\":\"cron.expression.set\",\"title\":\"Set CRON expression\",\"scope\":\"global\",\"targetKind\":\"expression\",\"target\":{\"kind\":\"expression\",\"resolver\":\"schedule-expression\",\"ambiguityPolicy\":\"fail\",\"required\":false},\"inputSchema\":{\"type\":\"object\",\"required\":[\"cron\"],\"properties\":{\"cron\":{\"type\":\"string\"},\"dialect\":{\"enum\":[\"unix\",\"quartz\",\"aws-eventbridge\",\"kubernetes\",\"github-actions\",\"gcp-scheduler\"]},\"seconds\":{\"type\":\"boolean\"}}},\"effects\":[{\"kind\":\"compile-domain-patch\",\"handler\":\"cron-expression-set\",\"handlerContract\":{\"reads\":[\"schedule.expression\",\"schedule.timezone\",\"metadata.timezone\",\"value\"],\"writes\":[\"schedule.kind\",\"schedule.expression\",\"value\",\"diagnostics\"],\"identityKeys\":[\"schedule.expression.cron\",\"schedule.expression.dialect\"],\"inputSchema\":{\"type\":\"object\",\"required\":[\"cron\"],\"properties\":{\"cron\":{\"type\":\"string\"},\"dialect\":{\"enum\":[\"unix\",\"quartz\",\"aws-eventbridge\",\"kubernetes\",\"github-actions\",\"gcp-scheduler\"]},\"seconds\":{\"type\":\"boolean\"}}},\"failureModes\":[\"invalid-expression\",\"invalid-dialect\",\"seconds-field-mismatch\"],\"description\":\"Validates and normalizes an explicit CRON expression before writing schedule.expression and the compatibility value.\"}}],\"destructive\":false,\"requiresConfirmation\":false,\"validators\":[\"cron-expression-valid\",\"cron-dialect-compatible\",\"editor-runtime-round-trip\"],\"affectedPaths\":[\"schedule.kind\",\"schedule.expression\",\"schedule.expression.cron\",\"schedule.expression.dialect\",\"schedule.expression.seconds\",\"value\",\"diagnostics\"],\"submissionImpact\":\"affects-submission\",\"preconditions\":[\"config-initialized\"]},{\"operationId\":\"cron.frequency.set\",\"title\":\"Set schedule frequency\",\"scope\":\"global\",\"targetKind\":\"frequency\",\"target\":{\"kind\":\"frequency\",\"resolver\":\"schedule-kind-and-recurrence\",\"ambiguityPolicy\":\"fail\",\"required\":false},\"inputSchema\":{\"type\":\"object\",\"required\":[\"kind\",\"recurrence\"],\"properties\":{\"kind\":{\"enum\":[\"once\",\"interval\",\"daily\",\"weekly\",\"monthly\",\"customCron\"]},\"recurrence\":{\"type\":\"object\"},\"dialect\":{\"enum\":[\"unix\",\"quartz\",\"aws-eventbridge\",\"kubernetes\",\"github-actions\",\"gcp-scheduler\"]}}},\"effects\":[{\"kind\":\"compile-domain-patch\",\"handler\":\"cron-frequency-to-expression\",\"handlerContract\":{\"reads\":[\"schedule.kind\",\"schedule.recurrence\",\"schedule.timezone\",\"schedule.expression.dialect\"],\"writes\":[\"schedule.kind\",\"schedule.recurrence\",\"schedule.expression\",\"value\"],\"identityKeys\":[\"schedule.kind\"],\"inputSchema\":{\"type\":\"object\",\"required\":[\"kind\",\"recurrence\"],\"properties\":{\"kind\":{\"enum\":[\"once\",\"interval\",\"daily\",\"weekly\",\"monthly\",\"customCron\"]},\"recurrence\":{\"type\":\"object\"},\"dialect\":{\"enum\":[\"unix\",\"quartz\",\"aws-eventbridge\",\"kubernetes\",\"github-actions\",\"gcp-scheduler\"]}}},\"failureModes\":[\"unsupported-kind\",\"non-portable-frequency\",\"invalid-recurrence\",\"cron-compile-failed\"],\"description\":\"Compiles structured recurrence intent through compileScheduleExpression and updates the canonical schedule expression only when diagnostics have no errors.\"}}],\"destructive\":false,\"requiresConfirmation\":false,\"validators\":[\"frequency-maps-to-canonical-expression\",\"cron-expression-valid\",\"diagnostics-before-patch\"],\"affectedPaths\":[\"schedule.kind\",\"schedule.recurrence\",\"schedule.expression\",\"value\"],\"submissionImpact\":\"affects-submission\",\"preconditions\":[\"config-initialized\"]},{\"operationId\":\"cron.timezone.set\",\"title\":\"Set schedule timezone\",\"scope\":\"global\",\"targetKind\":\"timezone\",\"target\":{\"kind\":\"timezone\",\"resolver\":\"schedule-timezone\",\"ambiguityPolicy\":\"fail\",\"required\":false},\"inputSchema\":{\"type\":\"object\",\"required\":[\"timezone\"],\"properties\":{\"timezone\":{\"type\":\"string\"}}},\"effects\":[{\"kind\":\"compile-domain-patch\",\"handler\":\"cron-timezone-set\",\"handlerContract\":{\"reads\":[\"value\",\"schedule\",\"metadata.timezone\",\"metadata.previewOccurrences\",\"metadata.previewFrom\",\"metadata.locale\"],\"writes\":[\"schedule.timezone\",\"metadata.timezone\",\"preview\",\"diagnostics\"],\"identityKeys\":[\"schedule.expression.cron\",\"schedule.timezone\"],\"inputSchema\":{\"type\":\"object\",\"required\":[\"timezone\"],\"properties\":{\"timezone\":{\"type\":\"string\"}}},\"failureModes\":[\"invalid-timezone\",\"invalid-expression\",\"preview-generation-failed\"],\"description\":\"Sets the IANA timezone used by schedule and metadata, then regenerates preview/diagnostics from the same expression.\"}}],\"destructive\":false,\"requiresConfirmation\":false,\"validators\":[\"timezone-valid\",\"preview-matches-expression\",\"editor-runtime-round-trip\"],\"affectedPaths\":[\"schedule.timezone\",\"metadata.timezone\",\"preview\",\"diagnostics\"],\"submissionImpact\":\"affects-submission\",\"preconditions\":[\"config-initialized\"]},{\"operationId\":\"cron.preset.apply\",\"title\":\"Apply CRON preset\",\"scope\":\"meta\",\"targetKind\":\"preset\",\"target\":{\"kind\":\"preset\",\"resolver\":\"cron-preset-by-label-or-expression\",\"ambiguityPolicy\":\"fail\",\"required\":true},\"inputSchema\":{\"type\":\"object\",\"required\":[\"labelOrCron\"],\"properties\":{\"labelOrCron\":{\"type\":\"string\"},\"timezone\":{\"type\":\"string\"}}},\"effects\":[{\"kind\":\"compile-domain-patch\",\"handler\":\"cron-preset-apply\",\"handlerContract\":{\"reads\":[\"metadata.presets[]\",\"presets[]\",\"schedule.timezone\",\"metadata.timezone\"],\"writes\":[\"schedule.kind\",\"schedule.expression\",\"schedule.timezone\",\"value\"],\"identityKeys\":[\"metadata.presets[].label\",\"metadata.presets[].cron\",\"presets[].label\",\"presets[].cron\"],\"inputSchema\":{\"type\":\"object\",\"required\":[\"labelOrCron\"],\"properties\":{\"labelOrCron\":{\"type\":\"string\"},\"timezone\":{\"type\":\"string\"}}},\"failureModes\":[\"preset-not-found\",\"preset-cron-invalid\",\"timezone-invalid\"],\"description\":\"Resolves a preset by label or cron, validates it through normalizeScheduleValue/createSchedulePreview, then applies the canonical expression.\"}}],\"destructive\":false,\"requiresConfirmation\":false,\"validators\":[\"preset-exists\",\"preset-maps-to-canonical-expression\",\"cron-expression-valid\"],\"affectedPaths\":[\"schedule.kind\",\"schedule.expression\",\"schedule.timezone\",\"value\"],\"submissionImpact\":\"affects-submission\",\"preconditions\":[\"config-initialized\",\"target-preset-exists\"]},{\"operationId\":\"cron.validate\",\"title\":\"Validate schedule\",\"scope\":\"global\",\"targetKind\":\"validation\",\"target\":{\"kind\":\"validation\",\"resolver\":\"schedule-validation-request\",\"ambiguityPolicy\":\"fail\",\"required\":false},\"inputSchema\":{\"type\":\"object\",\"properties\":{\"cron\":{\"type\":\"string\"},\"schedule\":{\"type\":\"object\"},\"timezone\":{\"type\":\"string\"},\"dialect\":{\"enum\":[\"unix\",\"quartz\",\"aws-eventbridge\",\"kubernetes\",\"github-actions\",\"gcp-scheduler\"]}}},\"effects\":[{\"kind\":\"compile-domain-patch\",\"handler\":\"cron-validation-diagnostics\",\"handlerContract\":{\"reads\":[\"value\",\"schedule\",\"metadata.timezone\"],\"writes\":[\"diagnostics\"],\"identityKeys\":[\"schedule.expression.cron\",\"schedule.timezone\"],\"inputSchema\":{\"type\":\"object\",\"properties\":{\"cron\":{\"type\":\"string\"},\"schedule\":{\"type\":\"object\"},\"timezone\":{\"type\":\"string\"},\"dialect\":{\"enum\":[\"unix\",\"quartz\",\"aws-eventbridge\",\"kubernetes\",\"github-actions\",\"gcp-scheduler\"]}}},\"failureModes\":[\"invalid-expression\",\"invalid-timezone\",\"invalid-recurrence\"],\"description\":\"Runs normalizeScheduleValue and validateScheduleAuthoringConfig and returns diagnostics without mutating schedule/value paths.\"}}],\"destructive\":false,\"requiresConfirmation\":false,\"validators\":[\"invalid-schedules-return-diagnostics\",\"cron-expression-valid\",\"timezone-valid\"],\"affectedPaths\":[\"diagnostics\"],\"submissionImpact\":\"none\",\"preconditions\":[\"config-initialized\"]}]}",
|
|
1587
1647
|
"sourcePointer": "projects/praxis-cron-builder/src/lib/ai/praxis-cron-builder-authoring-manifest.ts",
|
|
@@ -1591,7 +1651,7 @@
|
|
|
1591
1651
|
"corpusVersion": "1.0.0"
|
|
1592
1652
|
},
|
|
1593
1653
|
{
|
|
1594
|
-
"chunkIndex":
|
|
1654
|
+
"chunkIndex": 13,
|
|
1595
1655
|
"chunkKind": "authoring_manifest",
|
|
1596
1656
|
"content": "{\"schemaVersion\":\"1.0.0\",\"manifestVersion\":\"1.0.0\",\"componentId\":\"pdx-cron-builder\",\"ownerPackage\":\"@praxisui/cron-builder\",\"configSchemaId\":\"CronBuilderMetadata\",\"chunkSection\":\"operations\",\"operations\":[{\"operationId\":\"cron.preview.generate\",\"title\":\"Generate schedule preview\",\"scope\":\"global\",\"targetKind\":\"preview\",\"target\":{\"kind\":\"preview\",\"resolver\":\"schedule-preview-config\",\"ambiguityPolicy\":\"fail\",\"required\":false},\"inputSchema\":{\"type\":\"object\",\"properties\":{\"occurrences\":{\"type\":\"number\"},\"from\":{\"type\":\"string\"},\"timezone\":{\"type\":\"string\"},\"locale\":{\"type\":\"string\"}}},\"effects\":[{\"kind\":\"compile-domain-patch\",\"handler\":\"cron-preview-generate\",\"handlerContract\":{\"reads\":[\"value\",\"schedule\",\"metadata.previewOccurrences\",\"metadata.previewFrom\",\"metadata.timezone\",\"metadata.locale\"],\"writes\":[\"preview\",\"diagnostics\"],\"identityKeys\":[\"schedule.expression.cron\",\"schedule.timezone\",\"metadata.previewFrom\"],\"inputSchema\":{\"type\":\"object\",\"properties\":{\"occurrences\":{\"type\":\"number\"},\"from\":{\"type\":\"string\"},\"timezone\":{\"type\":\"string\"},\"locale\":{\"type\":\"string\"}}},\"failureModes\":[\"invalid-expression\",\"invalid-timezone\",\"preview-empty\",\"diagnostics-contain-errors\"],\"description\":\"Runs createSchedulePreview and returns read-only preview occurrences plus diagnostics; it does not patch the schedule when validation fails.\"}}],\"destructive\":false,\"requiresConfirmation\":false,\"validators\":[\"preview-matches-expression\",\"timezone-valid\",\"invalid-schedules-return-diagnostics\"],\"affectedPaths\":[\"preview\",\"diagnostics\"],\"submissionImpact\":\"none\",\"preconditions\":[\"config-initialized\"]}]}",
|
|
1597
1657
|
"sourcePointer": "projects/praxis-cron-builder/src/lib/ai/praxis-cron-builder-authoring-manifest.ts",
|
|
@@ -1601,7 +1661,7 @@
|
|
|
1601
1661
|
"corpusVersion": "1.0.0"
|
|
1602
1662
|
},
|
|
1603
1663
|
{
|
|
1604
|
-
"chunkIndex":
|
|
1664
|
+
"chunkIndex": 14,
|
|
1605
1665
|
"chunkKind": "authoring_manifest",
|
|
1606
1666
|
"content": "{\"schemaVersion\":\"1.0.0\",\"manifestVersion\":\"1.0.0\",\"componentId\":\"pdx-cron-builder\",\"ownerPackage\":\"@praxisui/cron-builder\",\"configSchemaId\":\"CronBuilderMetadata\",\"chunkSection\":\"validators\",\"validators\":[{\"validatorId\":\"cron-expression-valid\",\"level\":\"error\",\"code\":\"PCRON001\",\"description\":\"CRON expressions must pass the canonical cron-runtime parser for the selected dialect before schedule/value paths are patched.\"},{\"validatorId\":\"cron-dialect-compatible\",\"level\":\"error\",\"code\":\"PCRON002\",\"description\":\"Field count, seconds support and dialect-specific rules must match CRON_DIALECTS.\"},{\"validatorId\":\"timezone-valid\",\"level\":\"error\",\"code\":\"PCRON003\",\"description\":\"Timezone must be a valid IANA timezone accepted by Intl.DateTimeFormat and schedule preview.\"},{\"validatorId\":\"frequency-maps-to-canonical-expression\",\"level\":\"error\",\"code\":\"PCRON004\",\"description\":\"Structured frequency intent must compile through compileScheduleExpression into the canonical expression when portable.\"},{\"validatorId\":\"preset-exists\",\"level\":\"error\",\"code\":\"PCRON005\",\"description\":\"Preset operations must resolve an existing preset by label or cron expression.\"},{\"validatorId\":\"preset-maps-to-canonical-expression\",\"level\":\"error\",\"code\":\"PCRON006\",\"description\":\"Preset cron values must normalize into ScheduleAuthoringConfig and a valid canonical expression.\"},{\"validatorId\":\"preview-matches-expression\",\"level\":\"error\",\"code\":\"PCRON007\",\"description\":\"Preview occurrences must be generated from the same expression, timezone and from-date requested by authoring.\"},{\"validatorId\":\"invalid-schedules-return-diagnostics\",\"level\":\"error\",\"code\":\"PCRON008\",\"description\":\"Validation and preview requests for invalid schedules must return diagnostics and must not patch schedule/value fields.\"},{\"validatorId\":\"diagnostics-before-patch\",\"level\":\"error\",\"code\":\"PCRON009\",\"description\":\"Operations that compile recurrence or presets must evaluate diagnostics before mutating canonical schedule/value paths.\"},{\"validatorId\":\"editor-runtime-round-trip\",\"level\":\"error\",\"code\":\"PCRON010\",\"description\":\"ControlValueAccessor, runtime preview and AI adapter snapshots must preserve expression and timezone.\"}]}",
|
|
1607
1667
|
"sourcePointer": "projects/praxis-cron-builder/src/lib/ai/praxis-cron-builder-authoring-manifest.ts",
|
|
@@ -1611,7 +1671,7 @@
|
|
|
1611
1671
|
"corpusVersion": "1.0.0"
|
|
1612
1672
|
},
|
|
1613
1673
|
{
|
|
1614
|
-
"chunkIndex":
|
|
1674
|
+
"chunkIndex": 15,
|
|
1615
1675
|
"chunkKind": "authoring_manifest",
|
|
1616
1676
|
"content": "{\"schemaVersion\":\"1.0.0\",\"manifestVersion\":\"1.0.0\",\"componentId\":\"pdx-cron-builder\",\"ownerPackage\":\"@praxisui/cron-builder\",\"configSchemaId\":\"CronBuilderMetadata\",\"chunkSection\":\"roundTripRequirements\",\"roundTripRequirements\":[\"Expression and timezone edits must round-trip through ControlValueAccessor, normalizeScheduleValue and createSchedulePreview without losing the selected timezone.\",\"Structured frequency authoring must use ScheduleAuthoringConfig and compileScheduleExpression as the canonical source of recurrence semantics.\",\"Validation and preview operations are read-only: invalid schedules return diagnostics and must not mutate schedule/value paths.\",\"Preset operations must resolve stable label/cron identities and validate the resulting expression before applying it.\",\"Preview generation must use the same expression, timezone, locale, occurrences and from-date that are visible in the schedule config or metadata input.\"]}",
|
|
1617
1677
|
"sourcePointer": "projects/praxis-cron-builder/src/lib/ai/praxis-cron-builder-authoring-manifest.ts",
|
|
@@ -1621,7 +1681,7 @@
|
|
|
1621
1681
|
"corpusVersion": "1.0.0"
|
|
1622
1682
|
},
|
|
1623
1683
|
{
|
|
1624
|
-
"chunkIndex":
|
|
1684
|
+
"chunkIndex": 16,
|
|
1625
1685
|
"chunkKind": "authoring_manifest",
|
|
1626
1686
|
"content": "{\"schemaVersion\":\"1.0.0\",\"manifestVersion\":\"1.0.0\",\"componentId\":\"pdx-cron-builder\",\"ownerPackage\":\"@praxisui/cron-builder\",\"configSchemaId\":\"CronBuilderMetadata\",\"chunkSection\":\"examples\",\"examples\":[{\"id\":\"weekday-0800\",\"request\":\"Run every weekday at 08:00.\",\"operationId\":\"cron.frequency.set\",\"params\":{\"kind\":\"daily\",\"recurrence\":{\"daily\":{\"times\":[\"08:00\"],\"onlyWeekdays\":true}},\"dialect\":\"unix\"},\"isPositive\":true},{\"id\":\"every-15-minutes\",\"request\":\"Run every 15 minutes.\",\"operationId\":\"cron.frequency.set\",\"params\":{\"kind\":\"interval\",\"recurrence\":{\"interval\":{\"every\":15,\"unit\":\"minutes\"}},\"dialect\":\"unix\"},\"isPositive\":true},{\"id\":\"monthly-first-day\",\"request\":\"Run monthly on the first day at 09:00.\",\"operationId\":\"cron.frequency.set\",\"params\":{\"kind\":\"monthly\",\"recurrence\":{\"monthly\":{\"mode\":\"dayOfMonth\",\"dayOfMonth\":1,\"times\":[\"09:00\"]}},\"dialect\":\"unix\"},\"isPositive\":true},{\"id\":\"set-explicit-expression\",\"request\":\"Use cron expression 0 8 * * 1-5.\",\"operationId\":\"cron.expression.set\",\"params\":{\"cron\":\"0 8 * * 1-5\",\"dialect\":\"unix\",\"seconds\":false},\"isPositive\":true},{\"id\":\"change-timezone-preview\",\"request\":\"Change timezone to America/Sao_Paulo and preview the next runs.\",\"operationId\":\"cron.timezone.set\",\"params\":{\"timezone\":\"America/Sao_Paulo\"},\"isPositive\":true},{\"id\":\"preview-next-five\",\"request\":\"Preview the next five runs from 2026-04-20T00:00:00Z.\",\"operationId\":\"cron.preview.generate\",\"params\":{\"occurrences\":5,\"from\":\"2026-04-20T00:00:00.000Z\",\"timezone\":\"UTC\"},\"isPositive\":true},{\"id\":\"apply-business-hours-preset\",\"request\":\"Apply the business hours preset.\",\"operationId\":\"cron.preset.apply\",\"target\":\"business hours\",\"params\":{\"labelOrCron\":\"business hours\"},\"isPositive\":true},{\"id\":\"reject-impossible-expression\",\"request\":\"Use cron expression 99 99 * * *.\",\"operationId\":\"cron.expression.set\",\"params\":{\"cron\":\"99 99 * * *\",\"dialect\":\"unix\"},\"isPositive\":false},{\"id\":\"diagnose-invalid-expression\",\"request\":\"Validate 99 99 * * * and explain why it is invalid.\",\"operationId\":\"cron.validate\",\"params\":{\"cron\":\"99 99 * * *\",\"dialect\":\"unix\"},\"isPositive\":true},{\"id\":\"reject-invalid-timezone\",\"request\":\"Change timezone to Mars/Olympus.\",\"operationId\":\"cron.timezone.set\",\"params\":{\"timezone\":\"Mars/Olympus\"},\"isPositive\":false}]}",
|
|
1627
1687
|
"sourcePointer": "projects/praxis-cron-builder/src/lib/ai/praxis-cron-builder-authoring-manifest.ts",
|
|
@@ -1631,7 +1691,7 @@
|
|
|
1631
1691
|
"corpusVersion": "1.0.0"
|
|
1632
1692
|
},
|
|
1633
1693
|
{
|
|
1634
|
-
"chunkIndex":
|
|
1694
|
+
"chunkIndex": 17,
|
|
1635
1695
|
"chunkKind": "context_pack",
|
|
1636
1696
|
"content": "{\"componentContext\":{\"version\":\"v1\",\"optionsByPath\":{},\"actionCatalog\":[{\"id\":\"label.set\",\"intentExamples\":[\"label\",\"rótulo\",\"titulo\"],\"patchTemplate\":{\"label\":\"{{value}}\"}},{\"id\":\"hint.set\",\"intentExamples\":[\"hint\",\"help\",\"ajuda\"],\"patchTemplate\":{\"hint\":\"{{value}}\"}},{\"id\":\"enableSeconds.enable\",\"intentExamples\":[\"seconds\",\"segundos\",\"enable seconds\"],\"patchTemplate\":{\"enableSeconds\":true}},{\"id\":\"enableSeconds.disable\",\"intentExamples\":[\"disable seconds\",\"sem segundos\"],\"patchTemplate\":{\"enableSeconds\":false}},{\"id\":\"preset.add\",\"intentExamples\":[\"add preset\",\"new preset\",\"preset\"],\"patchTemplate\":{\"presets\":[{\"label\":\"{{value}}\",\"cron\":\"{{target}}\"}]}},{\"id\":\"preset.label.set\",\"intentExamples\":[\"rename preset\",\"preset label\"],\"patchTemplate\":{\"presets\":[{\"cron\":\"{{target}}\",\"label\":\"{{value}}\"}]}},{\"id\":\"preset.cron.set\",\"intentExamples\":[\"preset cron\",\"cron expression\"],\"patchTemplate\":{\"presets\":[{\"label\":\"{{target}}\",\"cron\":\"{{value}}\"}]}},{\"id\":\"schedule.daily.set\",\"intentExamples\":[\"daily\",\"diario\",\"diário\",\"every day\"],\"patchTemplate\":{\"schedule\":{\"kind\":\"daily\",\"timezone\":\"{{timezone}}\",\"recurrence\":{\"daily\":{\"times\":[\"{{value}}\"]}}}}},{\"id\":\"schedule.weekdays.set\",\"intentExamples\":[\"weekdays\",\"dias uteis\",\"dias úteis\",\"monday to friday\"],\"patchTemplate\":{\"schedule\":{\"kind\":\"daily\",\"timezone\":\"{{timezone}}\",\"recurrence\":{\"daily\":{\"times\":[\"{{value}}\"],\"onlyWeekdays\":true}}}}},{\"id\":\"schedule.timezone.set\",\"intentExamples\":[\"timezone\",\"fuso\",\"fuso horario\",\"fuso horário\"],\"patchTemplate\":{\"schedule\":{\"timezone\":\"{{value}}\"}}},{\"id\":\"schedule.concurrency.set\",\"intentExamples\":[\"concurrency\",\"concorrencia\",\"concorrência\",\"overlap\"],\"patchTemplate\":{\"schedule\":{\"executionPolicy\":{\"concurrencyPolicy\":\"{{value}}\"}}}}],\"fieldResolvers\":{\"presets[]\":[\"label\",\"cron\"]},\"hints\":[\"Use presets[].label or presets[].cron as merge keys; avoid array indexes.\",\"Prefer schedule.kind plus schedule.recurrence for business intent; use schedule.expression.cron only when the user explicitly asks for custom CRON.\",\"Cron expressions should be validated with diagnostics before applying to production.\"]}}",
|
|
1637
1697
|
"sourcePointer": "projects/praxis-cron-builder/src/lib/ai/cron-builder-context-pack.ts",
|
|
@@ -1641,7 +1701,7 @@
|
|
|
1641
1701
|
"corpusVersion": "1.0.0"
|
|
1642
1702
|
},
|
|
1643
1703
|
{
|
|
1644
|
-
"chunkIndex":
|
|
1704
|
+
"chunkIndex": 18,
|
|
1645
1705
|
"chunkKind": "recipe",
|
|
1646
1706
|
"content": "{\"_comment\":\"Recipe for pdx-cron-builder | controlType: cronBuilder\",\"templateMeta\":{\"registryKey\":\"praxis-cron-builder\",\"variantId\":\"base\",\"tags\":[\"dynamic-fields\",\"base\"],\"useWhen\":\"criar campo cronBuilder\",\"examplePrompts\":[\"crie um campo cronBuilder\",\"adicione um cronBuilder ao formulario\"]},\"fieldMetadata\":{\"name\":\"example_cronBuilder\",\"label\":\"Example cronBuilder\",\"placeholder\":\"example\",\"hint\":\"example\",\"tooltip\":\"example\",\"description\":\"example\",\"group\":\"example\",\"order\":1,\"width\":\"example\",\"isFlex\":true,\"controlType\":\"cronBuilder\",\"materialDesign\":{\"appearance\":\"fill\",\"color\":\"primary\",\"floatLabel\":\"auto\",\"subscriptSizing\":\"fixed\",\"hideRequiredMarker\":true,\"density\":\"comfortable\",\"disableRipple\":true,\"customPalette\":{\"example\":true},\"animations\":{\"example\":true}},\"prefixIcon\":\"example\",\"suffixIcon\":\"example\",\"iconPosition\":\"start\",\"iconSize\":\"small\",\"validators\":{\"example\":true,\"required\":true,\"email\":true,\"minLength\":1,\"maxLength\":1,\"min\":1,\"max\":1,\"pattern\":\"example\",\"minWords\":1,\"requiredChecked\":true},\"validationMode\":\"immediate\",\"debounceTime\":1,\"hidden\":true,\"visibleIn\":[\"form\"],\"formHidden\":true,\"tableHidden\":true,\"filterHidden\":true,\"dependencyFields\":[\"status\"],\"conditionalRequired\":{\"==\":[{\"var\":\"status\"},\"active\"]},\"conditionalDisplay\":{\"==\":[{\"var\":\"status\"},\"active\"]},\"dependencyFilterMap\":{\"example\":true},\"dependencyValuePath\":\"example\",\"dependencyMergeStrategy\":\"replace\",\"dependencyLoadOnChange\":\"respectLoadOn\",\"resetOnDependentChange\":true,\"dependencyDebounceMs\":1,\"transformDisplayValue\":\"formValue.status == 'active'\",\"transformSaveValue\":\"formValue.status == 'active'\",\"textTransformApply\":\"displayOnly\",\"inlineEditing\":true,\"unique\":true,\"readOnly\":true,\"disabled\":true,\"defaultValue\":\"default\",\"ariaLabel\":\"example\",\"ariaDescribedBy\":\"example\"}}",
|
|
1647
1707
|
"sourcePointer": "examples/ai-recipes/praxis-cron-builder/pdx-cron-builder.json",
|
|
@@ -2,7 +2,7 @@ import * as i0 from '@angular/core';
|
|
|
2
2
|
import { inject, forwardRef, Input, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
3
3
|
import * as i1 from '@angular/forms';
|
|
4
4
|
import { NonNullableFormBuilder, FormControl, ReactiveFormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
5
|
-
import * as
|
|
5
|
+
import * as i10 from '@angular/common';
|
|
6
6
|
import { CommonModule } from '@angular/common';
|
|
7
7
|
import * as i2 from '@angular/material/tabs';
|
|
8
8
|
import { MatTabsModule } from '@angular/material/tabs';
|
|
@@ -16,17 +16,15 @@ import * as i5 from '@angular/material/list';
|
|
|
16
16
|
import { MatListModule } from '@angular/material/list';
|
|
17
17
|
import * as i6 from '@angular/material/button';
|
|
18
18
|
import { MatButtonModule } from '@angular/material/button';
|
|
19
|
-
import * as i7 from '@angular/material/
|
|
20
|
-
import { MatIconModule } from '@angular/material/icon';
|
|
21
|
-
import * as i8 from '@angular/material/tooltip';
|
|
19
|
+
import * as i7 from '@angular/material/tooltip';
|
|
22
20
|
import { MatTooltipModule } from '@angular/material/tooltip';
|
|
23
|
-
import * as
|
|
21
|
+
import * as i8 from '@angular/material/slider';
|
|
24
22
|
import { MatSliderModule } from '@angular/material/slider';
|
|
25
|
-
import * as
|
|
23
|
+
import * as i9 from '@angular/material/chips';
|
|
26
24
|
import { MatChipsModule } from '@angular/material/chips';
|
|
27
25
|
import { MatSnackBar, MatSnackBarModule } from '@angular/material/snack-bar';
|
|
28
26
|
import { Clipboard } from '@angular/cdk/clipboard';
|
|
29
|
-
import {
|
|
27
|
+
import { PraxisIconButtonComponent } from '@praxisui/core';
|
|
30
28
|
import { Subject } from 'rxjs';
|
|
31
29
|
import { takeUntil } from 'rxjs/operators';
|
|
32
30
|
|
|
@@ -1188,7 +1186,7 @@ class PdxCronBuilderComponent {
|
|
|
1188
1186
|
useExisting: forwardRef(() => PdxCronBuilderComponent),
|
|
1189
1187
|
multi: true,
|
|
1190
1188
|
},
|
|
1191
|
-
], ngImport: i0, template: "<div class=\"cron-builder-container\" (focusout)=\"onTouched()\">\n @if (metadata.mode === 'both') {\n <mat-tab-group\n [selectedIndex]=\"selectedTabIndex\"\n (selectedTabChange)=\"onTabChange($event)\"\n >\n <mat-tab label=\"Simple\"></mat-tab>\n <mat-tab label=\"Advanced\"></mat-tab>\n </mat-tab-group>\n }\n\n @if (value) {\n <div class=\"cron-expression\">\n <mat-form-field appearance=\"outline\" class=\"cron-expression-field\">\n <mat-label>CRON Expression</mat-label>\n <input matInput [value]=\"value\" readonly />\n <button\n mat-icon-button\n matSuffix\n (click)=\"copyCron()\"\n [matTooltip]=\"'Copy to clipboard'\"\n aria-label=\"Copy CRON expression\"\n >\n <mat-icon [praxisIcon]=\"'content_copy'\"></mat-icon>\n </button>\n </mat-form-field>\n <button mat-button (click)=\"importCron()\">Import CRON</button>\n </div>\n }\n\n @switch (activeTab) {\n @case ('simple') {\n <div [formGroup]=\"simpleForm\" class=\"simple-mode\">\n <mat-form-field appearance=\"outline\" class=\"preset-select\">\n <mat-label>Preset</mat-label>\n <mat-select formControlName=\"type\">\n <mat-option value=\"everyNMinutes\">A cada X min</mat-option>\n <mat-option value=\"dailyAt\">Diariamente \u00E0s</mat-option>\n <mat-option value=\"weekly\">Semanal (dias marcados) \u00E0s</mat-option>\n <mat-option value=\"monthlyDay\">Mensal (dia N) \u00E0s</mat-option>\n <mat-option value=\"monthlyNthWeekday\">\n Mensal (N-\u00E9sima 2\u00AA-feira) \u00E0s\n </mat-option>\n </mat-select>\n </mat-form-field>\n\n @switch (simpleControls.type.value) {\n @case ('everyNMinutes') {\n <div class=\"preset-body\">\n <mat-slider\n min=\"1\"\n max=\"60\"\n step=\"1\"\n thumbLabel\n >\n <input matSliderThumb formControlName=\"everyN\" />\n </mat-slider>\n <div class=\"cron-hint\">\n A cada {{ simpleControls.everyN.value }} minutos\n </div>\n </div>\n }\n\n @case ('dailyAt') {\n <div class=\"preset-body\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Hora</mat-label>\n <input matInput type=\"time\" formControlName=\"dailyTime\" />\n </mat-form-field>\n <div class=\"cron-hint\">\n Diariamente \u00E0s {{ simpleControls.dailyTime.value }}\n </div>\n </div>\n }\n\n @case ('weekly') {\n <div class=\"preset-body\">\n <mat-chip-listbox formControlName=\"weeklyDays\" multiple>\n @for (day of weeklyDayOptions; track day) {\n <mat-chip-option [value]=\"day\">\n {{ weekdayLabels[day] }}\n </mat-chip-option>\n }\n </mat-chip-listbox>\n <mat-form-field appearance=\"outline\">\n <mat-label>Hora</mat-label>\n <input matInput type=\"time\" formControlName=\"weeklyTime\" />\n </mat-form-field>\n <div class=\"cron-hint\">\n Semanalmente \u00E0s {{ simpleControls.weeklyTime.value }}\n </div>\n </div>\n }\n\n @case ('monthlyDay') {\n <div class=\"preset-body\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Dia</mat-label>\n <input\n matInput\n type=\"number\"\n formControlName=\"monthlyDay\"\n min=\"1\"\n max=\"31\"\n />\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Hora</mat-label>\n <input matInput type=\"time\" formControlName=\"monthlyTime\" />\n </mat-form-field>\n <div class=\"cron-hint\">\n Dia {{ simpleControls.monthlyDay.value }} \u00E0s\n {{ simpleControls.monthlyTime.value }}\n </div>\n </div>\n }\n\n @case ('monthlyNthWeekday') {\n <div class=\"preset-body\">\n <mat-form-field appearance=\"outline\">\n <mat-label>N-\u00E9sima</mat-label>\n <mat-select formControlName=\"nth\">\n @for (nth of nthOrderOptions; track nth) {\n <mat-option [value]=\"nth\">{{ nth }}\u00AA</mat-option>\n }\n </mat-select>\n </mat-form-field>\n <mat-chip-listbox formControlName=\"nthDay\">\n @for (day of nthDayOptions; track day) {\n <mat-chip-option [value]=\"day\">\n {{ weekdayLabels[day] }}\n </mat-chip-option>\n }\n </mat-chip-listbox>\n <mat-form-field appearance=\"outline\">\n <mat-label>Hora</mat-label>\n <input matInput type=\"time\" formControlName=\"nthTime\" />\n </mat-form-field>\n <div class=\"cron-hint\">\n {{ simpleControls.nth.value }}\u00AA\n {{ weekdayLabels[simpleControls.nthDay.value] }}\n \u00E0s\n {{ simpleControls.nthTime.value }}\n </div>\n </div>\n }\n }\n </div>\n }\n\n @case ('advanced') {\n <div [formGroup]=\"form\">\n <div class=\"cron-fields\">\n @if (metadata.fields?.minutes) {\n <mat-form-field>\n <mat-label>Minutes</mat-label>\n <input matInput formControlName=\"minutes\" />\n </mat-form-field>\n }\n @if (metadata.fields?.hours) {\n <mat-form-field>\n <mat-label>Hours</mat-label>\n <input matInput formControlName=\"hours\" />\n </mat-form-field>\n }\n @if (metadata.fields?.dom) {\n <mat-form-field>\n <mat-label>Day of Month</mat-label>\n <input matInput formControlName=\"dayOfMonth\" />\n </mat-form-field>\n }\n @if (metadata.fields?.month) {\n <mat-form-field>\n <mat-label>Month</mat-label>\n <input matInput formControlName=\"month\" />\n </mat-form-field>\n }\n @if (metadata.fields?.dow) {\n <mat-form-field>\n <mat-label>Day of Week</mat-label>\n <input matInput formControlName=\"dayOfWeek\" />\n </mat-form-field>\n }\n @if (metadata.fields?.seconds) {\n <mat-form-field>\n <mat-label>Seconds</mat-label>\n <input matInput formControlName=\"seconds\" />\n </mat-form-field>\n }\n </div>\n </div>\n }\n }\n\n <div class=\"cron-feedback\">\n <mat-form-field appearance=\"outline\" class=\"timezone-field\">\n <mat-label>Timezone</mat-label>\n <mat-select [formControl]=\"timezoneControl\">\n @for (tz of timezoneOptions; track tz) {\n <mat-option [value]=\"tz\">\n {{ tz }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n\n @if (humanized) {\n <div class=\"humanized-description\" aria-live=\"polite\">\n {{ humanized }}\n <button\n mat-icon-button\n class=\"copy-humanized\"\n (click)=\"copyHumanized()\"\n [matTooltip]=\"'Copy description'\"\n aria-label=\"Copy description\"\n >\n <mat-icon [praxisIcon]=\"'content_copy'\"></mat-icon>\n </button>\n </div>\n }\n\n @if (error) {\n <div class=\"cron-error\">{{ error }}</div>\n }\n\n @if (preview.length > 0) {\n <div class=\"preview-section\">\n <h4>Next Occurrences:</h4>\n <mat-list>\n @for (date of preview; track $index) {\n <mat-list-item>\n {{\n date\n | date\n : \"full\"\n : timezoneControl.value\n : metadata.locale || \"pt-BR\"\n }}\n </mat-list-item>\n }\n </mat-list>\n </div>\n }\n </div>\n\n @if (metadata.hint) {\n <div class=\"cron-hint\">{{ metadata.hint }}</div>\n }\n</div>\n", styles: [":host{display:block}.cron-expression-field{width:100%}.cron-expression{margin-bottom:1rem}.simple-mode{display:flex;flex-direction:column;gap:1rem}.preset-body{display:flex;flex-direction:column;gap:.5rem}.cron-feedback{margin-top:1rem;display:flex;flex-direction:column;gap:.5rem}.humanized-description{display:flex;align-items:center;gap:.5rem}.timezone-field{width:250px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i2.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i2.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "ngmodule", type: MatRadioModule }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: i3.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i3.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i4.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "ngmodule", type: MatListModule }, { kind: "component", type: i5.MatList, selector: "mat-list", exportAs: ["matList"] }, { kind: "component", type: i5.MatListItem, selector: "mat-list-item, a[mat-list-item], button[mat-list-item]", inputs: ["activated"], exportAs: ["matListItem"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i6.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "component", type: i6.MatIconButton, selector: "button[mat-icon-button], a[mat-icon-button], button[matIconButton], a[matIconButton]", exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatIconModule }, { kind: "component", type: i7.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i8.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatSliderModule }, { kind: "component", type: i9.MatSlider, selector: "mat-slider", inputs: ["disabled", "discrete", "showTickMarks", "min", "color", "disableRipple", "max", "step", "displayWith"], exportAs: ["matSlider"] }, { kind: "directive", type: i9.MatSliderThumb, selector: "input[matSliderThumb]", inputs: ["value"], outputs: ["valueChange", "dragStart", "dragEnd"], exportAs: ["matSliderThumb"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i10.MatChipListbox, selector: "mat-chip-listbox", inputs: ["multiple", "aria-orientation", "selectable", "compareWith", "required", "hideSingleSelectionIndicator", "value"], outputs: ["change"] }, { kind: "component", type: i10.MatChipOption, selector: "mat-basic-chip-option, [mat-basic-chip-option], mat-chip-option, [mat-chip-option]", inputs: ["selectable", "selected"], outputs: ["selectionChange"] }, { kind: "ngmodule", type: MatSnackBarModule }, { kind: "directive", type: PraxisIconDirective, selector: "mat-icon[praxisIcon]", inputs: ["praxisIcon"] }, { kind: "pipe", type: i11.DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1189
|
+
], ngImport: i0, template: "<div class=\"cron-builder-container\" (focusout)=\"onTouched()\">\n @if (metadata.mode === 'both') {\n <mat-tab-group\n [selectedIndex]=\"selectedTabIndex\"\n (selectedTabChange)=\"onTabChange($event)\"\n >\n <mat-tab label=\"Simple\"></mat-tab>\n <mat-tab label=\"Advanced\"></mat-tab>\n </mat-tab-group>\n }\n\n @if (value) {\n <div class=\"cron-expression\">\n <mat-form-field appearance=\"outline\" class=\"cron-expression-field\">\n <mat-label>CRON Expression</mat-label>\n <input matInput [value]=\"value\" readonly />\n <button\n praxisIconButton=\"content_copy\"\n size=\"dense\"\n matSuffix\n type=\"button\"\n (click)=\"copyCron()\"\n [matTooltip]=\"'Copy to clipboard'\"\n aria-label=\"Copy CRON expression\"\n ></button>\n </mat-form-field>\n <button mat-button (click)=\"importCron()\">Import CRON</button>\n </div>\n }\n\n @switch (activeTab) {\n @case ('simple') {\n <div [formGroup]=\"simpleForm\" class=\"simple-mode\">\n <mat-form-field appearance=\"outline\" class=\"preset-select\">\n <mat-label>Preset</mat-label>\n <mat-select formControlName=\"type\">\n <mat-option value=\"everyNMinutes\">A cada X min</mat-option>\n <mat-option value=\"dailyAt\">Diariamente \u00E0s</mat-option>\n <mat-option value=\"weekly\">Semanal (dias marcados) \u00E0s</mat-option>\n <mat-option value=\"monthlyDay\">Mensal (dia N) \u00E0s</mat-option>\n <mat-option value=\"monthlyNthWeekday\">\n Mensal (N-\u00E9sima 2\u00AA-feira) \u00E0s\n </mat-option>\n </mat-select>\n </mat-form-field>\n\n @switch (simpleControls.type.value) {\n @case ('everyNMinutes') {\n <div class=\"preset-body\">\n <mat-slider\n min=\"1\"\n max=\"60\"\n step=\"1\"\n thumbLabel\n >\n <input matSliderThumb formControlName=\"everyN\" />\n </mat-slider>\n <div class=\"cron-hint\">\n A cada {{ simpleControls.everyN.value }} minutos\n </div>\n </div>\n }\n\n @case ('dailyAt') {\n <div class=\"preset-body\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Hora</mat-label>\n <input matInput type=\"time\" formControlName=\"dailyTime\" />\n </mat-form-field>\n <div class=\"cron-hint\">\n Diariamente \u00E0s {{ simpleControls.dailyTime.value }}\n </div>\n </div>\n }\n\n @case ('weekly') {\n <div class=\"preset-body\">\n <mat-chip-listbox formControlName=\"weeklyDays\" multiple>\n @for (day of weeklyDayOptions; track day) {\n <mat-chip-option [value]=\"day\">\n {{ weekdayLabels[day] }}\n </mat-chip-option>\n }\n </mat-chip-listbox>\n <mat-form-field appearance=\"outline\">\n <mat-label>Hora</mat-label>\n <input matInput type=\"time\" formControlName=\"weeklyTime\" />\n </mat-form-field>\n <div class=\"cron-hint\">\n Semanalmente \u00E0s {{ simpleControls.weeklyTime.value }}\n </div>\n </div>\n }\n\n @case ('monthlyDay') {\n <div class=\"preset-body\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Dia</mat-label>\n <input\n matInput\n type=\"number\"\n formControlName=\"monthlyDay\"\n min=\"1\"\n max=\"31\"\n />\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Hora</mat-label>\n <input matInput type=\"time\" formControlName=\"monthlyTime\" />\n </mat-form-field>\n <div class=\"cron-hint\">\n Dia {{ simpleControls.monthlyDay.value }} \u00E0s\n {{ simpleControls.monthlyTime.value }}\n </div>\n </div>\n }\n\n @case ('monthlyNthWeekday') {\n <div class=\"preset-body\">\n <mat-form-field appearance=\"outline\">\n <mat-label>N-\u00E9sima</mat-label>\n <mat-select formControlName=\"nth\">\n @for (nth of nthOrderOptions; track nth) {\n <mat-option [value]=\"nth\">{{ nth }}\u00AA</mat-option>\n }\n </mat-select>\n </mat-form-field>\n <mat-chip-listbox formControlName=\"nthDay\">\n @for (day of nthDayOptions; track day) {\n <mat-chip-option [value]=\"day\">\n {{ weekdayLabels[day] }}\n </mat-chip-option>\n }\n </mat-chip-listbox>\n <mat-form-field appearance=\"outline\">\n <mat-label>Hora</mat-label>\n <input matInput type=\"time\" formControlName=\"nthTime\" />\n </mat-form-field>\n <div class=\"cron-hint\">\n {{ simpleControls.nth.value }}\u00AA\n {{ weekdayLabels[simpleControls.nthDay.value] }}\n \u00E0s\n {{ simpleControls.nthTime.value }}\n </div>\n </div>\n }\n }\n </div>\n }\n\n @case ('advanced') {\n <div [formGroup]=\"form\">\n <div class=\"cron-fields\">\n @if (metadata.fields?.minutes) {\n <mat-form-field>\n <mat-label>Minutes</mat-label>\n <input matInput formControlName=\"minutes\" />\n </mat-form-field>\n }\n @if (metadata.fields?.hours) {\n <mat-form-field>\n <mat-label>Hours</mat-label>\n <input matInput formControlName=\"hours\" />\n </mat-form-field>\n }\n @if (metadata.fields?.dom) {\n <mat-form-field>\n <mat-label>Day of Month</mat-label>\n <input matInput formControlName=\"dayOfMonth\" />\n </mat-form-field>\n }\n @if (metadata.fields?.month) {\n <mat-form-field>\n <mat-label>Month</mat-label>\n <input matInput formControlName=\"month\" />\n </mat-form-field>\n }\n @if (metadata.fields?.dow) {\n <mat-form-field>\n <mat-label>Day of Week</mat-label>\n <input matInput formControlName=\"dayOfWeek\" />\n </mat-form-field>\n }\n @if (metadata.fields?.seconds) {\n <mat-form-field>\n <mat-label>Seconds</mat-label>\n <input matInput formControlName=\"seconds\" />\n </mat-form-field>\n }\n </div>\n </div>\n }\n }\n\n <div class=\"cron-feedback\">\n <mat-form-field appearance=\"outline\" class=\"timezone-field\">\n <mat-label>Timezone</mat-label>\n <mat-select [formControl]=\"timezoneControl\">\n @for (tz of timezoneOptions; track tz) {\n <mat-option [value]=\"tz\">\n {{ tz }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n\n @if (humanized) {\n <div class=\"humanized-description\" aria-live=\"polite\">\n {{ humanized }}\n <button\n praxisIconButton=\"content_copy\"\n size=\"compact\"\n class=\"copy-humanized\"\n type=\"button\"\n (click)=\"copyHumanized()\"\n [matTooltip]=\"'Copy description'\"\n aria-label=\"Copy description\"\n ></button>\n </div>\n }\n\n @if (error) {\n <div class=\"cron-error\">{{ error }}</div>\n }\n\n @if (preview.length > 0) {\n <div class=\"preview-section\">\n <h4>Next Occurrences:</h4>\n <mat-list>\n @for (date of preview; track $index) {\n <mat-list-item>\n {{\n date\n | date\n : \"full\"\n : timezoneControl.value\n : metadata.locale || \"pt-BR\"\n }}\n </mat-list-item>\n }\n </mat-list>\n </div>\n }\n </div>\n\n @if (metadata.hint) {\n <div class=\"cron-hint\">{{ metadata.hint }}</div>\n }\n</div>\n", styles: [":host{display:block}.cron-expression-field{width:100%}.cron-expression{margin-bottom:1rem}.simple-mode{display:flex;flex-direction:column;gap:1rem}.preset-body{display:flex;flex-direction:column;gap:.5rem}.cron-feedback{margin-top:1rem;display:flex;flex-direction:column;gap:.5rem}.humanized-description{display:flex;align-items:center;gap:.5rem}.timezone-field{width:250px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i2.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass", "id"], exportAs: ["matTab"] }, { kind: "component", type: i2.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "mat-align-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "ngmodule", type: MatRadioModule }, { kind: "ngmodule", type: MatSelectModule }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: i3.MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth", "canSelectNullableOptions"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: i3.MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "ngmodule", type: MatInputModule }, { kind: "directive", type: i4.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly", "disabledInteractive"], exportAs: ["matInput"] }, { kind: "ngmodule", type: MatFormFieldModule }, { kind: "ngmodule", type: MatListModule }, { kind: "component", type: i5.MatList, selector: "mat-list", exportAs: ["matList"] }, { kind: "component", type: i5.MatListItem, selector: "mat-list-item, a[mat-list-item], button[mat-list-item]", inputs: ["activated"], exportAs: ["matListItem"] }, { kind: "ngmodule", type: MatButtonModule }, { kind: "component", type: i6.MatButton, selector: " button[matButton], a[matButton], button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button], a[mat-button], a[mat-raised-button], a[mat-flat-button], a[mat-stroked-button] ", inputs: ["matButton"], exportAs: ["matButton", "matAnchor"] }, { kind: "ngmodule", type: MatTooltipModule }, { kind: "directive", type: i7.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: MatSliderModule }, { kind: "component", type: i8.MatSlider, selector: "mat-slider", inputs: ["disabled", "discrete", "showTickMarks", "min", "color", "disableRipple", "max", "step", "displayWith"], exportAs: ["matSlider"] }, { kind: "directive", type: i8.MatSliderThumb, selector: "input[matSliderThumb]", inputs: ["value"], outputs: ["valueChange", "dragStart", "dragEnd"], exportAs: ["matSliderThumb"] }, { kind: "ngmodule", type: MatChipsModule }, { kind: "component", type: i9.MatChipListbox, selector: "mat-chip-listbox", inputs: ["multiple", "aria-orientation", "selectable", "compareWith", "required", "hideSingleSelectionIndicator", "value"], outputs: ["change"] }, { kind: "component", type: i9.MatChipOption, selector: "mat-basic-chip-option, [mat-basic-chip-option], mat-chip-option, [mat-chip-option]", inputs: ["selectable", "selected"], outputs: ["selectionChange"] }, { kind: "ngmodule", type: MatSnackBarModule }, { kind: "component", type: PraxisIconButtonComponent, selector: "button[praxisIconButton]", inputs: ["praxisIconButton", "size", "appearance", "presentation", "pressed", "busy"] }, { kind: "pipe", type: i10.DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1192
1190
|
}
|
|
1193
1191
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImport: i0, type: PdxCronBuilderComponent, decorators: [{
|
|
1194
1192
|
type: Component,
|
|
@@ -1202,19 +1200,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.14", ngImpo
|
|
|
1202
1200
|
MatFormFieldModule,
|
|
1203
1201
|
MatListModule,
|
|
1204
1202
|
MatButtonModule,
|
|
1205
|
-
MatIconModule,
|
|
1206
1203
|
MatTooltipModule,
|
|
1207
1204
|
MatSliderModule,
|
|
1208
1205
|
MatChipsModule,
|
|
1209
1206
|
MatSnackBarModule,
|
|
1210
|
-
|
|
1207
|
+
PraxisIconButtonComponent,
|
|
1211
1208
|
], changeDetection: ChangeDetectionStrategy.OnPush, providers: [
|
|
1212
1209
|
{
|
|
1213
1210
|
provide: NG_VALUE_ACCESSOR,
|
|
1214
1211
|
useExisting: forwardRef(() => PdxCronBuilderComponent),
|
|
1215
1212
|
multi: true,
|
|
1216
1213
|
},
|
|
1217
|
-
], template: "<div class=\"cron-builder-container\" (focusout)=\"onTouched()\">\n @if (metadata.mode === 'both') {\n <mat-tab-group\n [selectedIndex]=\"selectedTabIndex\"\n (selectedTabChange)=\"onTabChange($event)\"\n >\n <mat-tab label=\"Simple\"></mat-tab>\n <mat-tab label=\"Advanced\"></mat-tab>\n </mat-tab-group>\n }\n\n @if (value) {\n <div class=\"cron-expression\">\n <mat-form-field appearance=\"outline\" class=\"cron-expression-field\">\n <mat-label>CRON Expression</mat-label>\n <input matInput [value]=\"value\" readonly />\n <button\n
|
|
1214
|
+
], template: "<div class=\"cron-builder-container\" (focusout)=\"onTouched()\">\n @if (metadata.mode === 'both') {\n <mat-tab-group\n [selectedIndex]=\"selectedTabIndex\"\n (selectedTabChange)=\"onTabChange($event)\"\n >\n <mat-tab label=\"Simple\"></mat-tab>\n <mat-tab label=\"Advanced\"></mat-tab>\n </mat-tab-group>\n }\n\n @if (value) {\n <div class=\"cron-expression\">\n <mat-form-field appearance=\"outline\" class=\"cron-expression-field\">\n <mat-label>CRON Expression</mat-label>\n <input matInput [value]=\"value\" readonly />\n <button\n praxisIconButton=\"content_copy\"\n size=\"dense\"\n matSuffix\n type=\"button\"\n (click)=\"copyCron()\"\n [matTooltip]=\"'Copy to clipboard'\"\n aria-label=\"Copy CRON expression\"\n ></button>\n </mat-form-field>\n <button mat-button (click)=\"importCron()\">Import CRON</button>\n </div>\n }\n\n @switch (activeTab) {\n @case ('simple') {\n <div [formGroup]=\"simpleForm\" class=\"simple-mode\">\n <mat-form-field appearance=\"outline\" class=\"preset-select\">\n <mat-label>Preset</mat-label>\n <mat-select formControlName=\"type\">\n <mat-option value=\"everyNMinutes\">A cada X min</mat-option>\n <mat-option value=\"dailyAt\">Diariamente \u00E0s</mat-option>\n <mat-option value=\"weekly\">Semanal (dias marcados) \u00E0s</mat-option>\n <mat-option value=\"monthlyDay\">Mensal (dia N) \u00E0s</mat-option>\n <mat-option value=\"monthlyNthWeekday\">\n Mensal (N-\u00E9sima 2\u00AA-feira) \u00E0s\n </mat-option>\n </mat-select>\n </mat-form-field>\n\n @switch (simpleControls.type.value) {\n @case ('everyNMinutes') {\n <div class=\"preset-body\">\n <mat-slider\n min=\"1\"\n max=\"60\"\n step=\"1\"\n thumbLabel\n >\n <input matSliderThumb formControlName=\"everyN\" />\n </mat-slider>\n <div class=\"cron-hint\">\n A cada {{ simpleControls.everyN.value }} minutos\n </div>\n </div>\n }\n\n @case ('dailyAt') {\n <div class=\"preset-body\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Hora</mat-label>\n <input matInput type=\"time\" formControlName=\"dailyTime\" />\n </mat-form-field>\n <div class=\"cron-hint\">\n Diariamente \u00E0s {{ simpleControls.dailyTime.value }}\n </div>\n </div>\n }\n\n @case ('weekly') {\n <div class=\"preset-body\">\n <mat-chip-listbox formControlName=\"weeklyDays\" multiple>\n @for (day of weeklyDayOptions; track day) {\n <mat-chip-option [value]=\"day\">\n {{ weekdayLabels[day] }}\n </mat-chip-option>\n }\n </mat-chip-listbox>\n <mat-form-field appearance=\"outline\">\n <mat-label>Hora</mat-label>\n <input matInput type=\"time\" formControlName=\"weeklyTime\" />\n </mat-form-field>\n <div class=\"cron-hint\">\n Semanalmente \u00E0s {{ simpleControls.weeklyTime.value }}\n </div>\n </div>\n }\n\n @case ('monthlyDay') {\n <div class=\"preset-body\">\n <mat-form-field appearance=\"outline\">\n <mat-label>Dia</mat-label>\n <input\n matInput\n type=\"number\"\n formControlName=\"monthlyDay\"\n min=\"1\"\n max=\"31\"\n />\n </mat-form-field>\n <mat-form-field appearance=\"outline\">\n <mat-label>Hora</mat-label>\n <input matInput type=\"time\" formControlName=\"monthlyTime\" />\n </mat-form-field>\n <div class=\"cron-hint\">\n Dia {{ simpleControls.monthlyDay.value }} \u00E0s\n {{ simpleControls.monthlyTime.value }}\n </div>\n </div>\n }\n\n @case ('monthlyNthWeekday') {\n <div class=\"preset-body\">\n <mat-form-field appearance=\"outline\">\n <mat-label>N-\u00E9sima</mat-label>\n <mat-select formControlName=\"nth\">\n @for (nth of nthOrderOptions; track nth) {\n <mat-option [value]=\"nth\">{{ nth }}\u00AA</mat-option>\n }\n </mat-select>\n </mat-form-field>\n <mat-chip-listbox formControlName=\"nthDay\">\n @for (day of nthDayOptions; track day) {\n <mat-chip-option [value]=\"day\">\n {{ weekdayLabels[day] }}\n </mat-chip-option>\n }\n </mat-chip-listbox>\n <mat-form-field appearance=\"outline\">\n <mat-label>Hora</mat-label>\n <input matInput type=\"time\" formControlName=\"nthTime\" />\n </mat-form-field>\n <div class=\"cron-hint\">\n {{ simpleControls.nth.value }}\u00AA\n {{ weekdayLabels[simpleControls.nthDay.value] }}\n \u00E0s\n {{ simpleControls.nthTime.value }}\n </div>\n </div>\n }\n }\n </div>\n }\n\n @case ('advanced') {\n <div [formGroup]=\"form\">\n <div class=\"cron-fields\">\n @if (metadata.fields?.minutes) {\n <mat-form-field>\n <mat-label>Minutes</mat-label>\n <input matInput formControlName=\"minutes\" />\n </mat-form-field>\n }\n @if (metadata.fields?.hours) {\n <mat-form-field>\n <mat-label>Hours</mat-label>\n <input matInput formControlName=\"hours\" />\n </mat-form-field>\n }\n @if (metadata.fields?.dom) {\n <mat-form-field>\n <mat-label>Day of Month</mat-label>\n <input matInput formControlName=\"dayOfMonth\" />\n </mat-form-field>\n }\n @if (metadata.fields?.month) {\n <mat-form-field>\n <mat-label>Month</mat-label>\n <input matInput formControlName=\"month\" />\n </mat-form-field>\n }\n @if (metadata.fields?.dow) {\n <mat-form-field>\n <mat-label>Day of Week</mat-label>\n <input matInput formControlName=\"dayOfWeek\" />\n </mat-form-field>\n }\n @if (metadata.fields?.seconds) {\n <mat-form-field>\n <mat-label>Seconds</mat-label>\n <input matInput formControlName=\"seconds\" />\n </mat-form-field>\n }\n </div>\n </div>\n }\n }\n\n <div class=\"cron-feedback\">\n <mat-form-field appearance=\"outline\" class=\"timezone-field\">\n <mat-label>Timezone</mat-label>\n <mat-select [formControl]=\"timezoneControl\">\n @for (tz of timezoneOptions; track tz) {\n <mat-option [value]=\"tz\">\n {{ tz }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n\n @if (humanized) {\n <div class=\"humanized-description\" aria-live=\"polite\">\n {{ humanized }}\n <button\n praxisIconButton=\"content_copy\"\n size=\"compact\"\n class=\"copy-humanized\"\n type=\"button\"\n (click)=\"copyHumanized()\"\n [matTooltip]=\"'Copy description'\"\n aria-label=\"Copy description\"\n ></button>\n </div>\n }\n\n @if (error) {\n <div class=\"cron-error\">{{ error }}</div>\n }\n\n @if (preview.length > 0) {\n <div class=\"preview-section\">\n <h4>Next Occurrences:</h4>\n <mat-list>\n @for (date of preview; track $index) {\n <mat-list-item>\n {{\n date\n | date\n : \"full\"\n : timezoneControl.value\n : metadata.locale || \"pt-BR\"\n }}\n </mat-list-item>\n }\n </mat-list>\n </div>\n }\n </div>\n\n @if (metadata.hint) {\n <div class=\"cron-hint\">{{ metadata.hint }}</div>\n }\n</div>\n", styles: [":host{display:block}.cron-expression-field{width:100%}.cron-expression{margin-bottom:1rem}.simple-mode{display:flex;flex-direction:column;gap:1rem}.preset-body{display:flex;flex-direction:column;gap:.5rem}.cron-feedback{margin-top:1rem;display:flex;flex-direction:column;gap:.5rem}.humanized-description{display:flex;align-items:center;gap:.5rem}.timezone-field{width:250px}\n"] }]
|
|
1218
1215
|
}], ctorParameters: () => [], propDecorators: { metadata: [{
|
|
1219
1216
|
type: Input
|
|
1220
1217
|
}] } });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@praxisui/cron-builder",
|
|
3
|
-
"version": "9.0.0-beta.
|
|
3
|
+
"version": "9.0.0-beta.88",
|
|
4
4
|
"description": "Cron expression builder utilities and components for Praxis UI.",
|
|
5
5
|
"peerDependencies": {
|
|
6
6
|
"@angular/common": "^21.0.0",
|
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
"@angular/forms": "^21.0.0",
|
|
9
9
|
"@angular/cdk": "^21.0.0",
|
|
10
10
|
"@angular/material": "^21.0.0",
|
|
11
|
-
"@praxisui/core": "^9.0.0-beta.
|
|
12
|
-
"@praxisui/ai": "^9.0.0-beta.
|
|
11
|
+
"@praxisui/core": "^9.0.0-beta.88",
|
|
12
|
+
"@praxisui/ai": "^9.0.0-beta.88",
|
|
13
13
|
"rxjs": "~7.8.0"
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|