@salsita-ai/sdk 0.50.0-develop.da56a0c6c3 → 0.50.0-develop.dfac20c66b
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -11
- package/dist/application-spec/errors/diagnostic-codes.d.ts +6 -0
- package/dist/application-spec/errors/diagnostic-codes.js +1 -1
- package/dist/application-spec/errors/diagnostic-messages.d.ts +6 -0
- package/dist/application-spec/errors/diagnostic-messages.js +1 -1
- package/dist/application-spec/generate-application/code/domain-runtime-files.js +1 -1
- package/dist/application-spec/generate-application/code/templates/application-types.js +6 -6
- package/dist/application-spec/generate-application/code/templates/configurator-domain-code.d.ts +1 -0
- package/dist/application-spec/generate-application/code/templates/configurator-domain-code.js +11 -8
- package/dist/application-spec/generate-application/code/templates/domain-spec/generate-domain-block.d.ts +3 -1
- package/dist/application-spec/generate-application/code/templates/domain-spec/generate-domain-block.js +70 -66
- package/dist/application-spec/generate-application/code/templates/domain-spec/generate-phx-globals.js +3 -0
- package/dist/application-spec/generate-application/code/templates/domain-spec.js +5 -5
- package/dist/application-spec/generate-application/code/templates/domain.js +2 -2
- package/dist/application-spec/generate-application/code/templates/global-definition/generate-action-types.d.ts +11 -0
- package/dist/application-spec/generate-application/code/templates/global-definition/generate-action-types.js +8 -0
- package/dist/application-spec/generate-application/code/templates/global-definition/index.d.ts +1 -0
- package/dist/application-spec/generate-application/code/templates/global-definition/index.js +1 -1
- package/dist/application-spec/generate-application/code/templates/globals.js +1 -0
- package/dist/application-spec/generate-application/code/templates/skills/phoenix-create-configurator-skill.js +3 -1
- package/dist/application-spec/generate-application/code/templates/skills/phoenix-feedback-skill.js +39 -16
- package/dist/application-spec/generate-application/code/templates/skills/phoenix-review-skill.js +4 -2
- package/dist/application-spec/generate-application/code/templates/skills/sdk-content.d.ts +3 -1
- package/dist/application-spec/generate-application/code/templates/skills/sdk-content.js +2 -2
- package/dist/application-spec/generate-application/runtime/configurator-runtime/configurator-runtime.d.ts +2 -0
- package/dist/application-spec/generate-application/runtime/configurator-runtime/configurator-runtime.js +1 -1
- package/dist/application-spec/generate-application/runtime/sections/actions-runtime.d.ts +14 -0
- package/dist/application-spec/generate-application/runtime/sections/actions-runtime.js +1 -0
- package/dist/application-spec/generate-application/runtime/sections/index.d.ts +1 -0
- package/dist/application-spec/generate-application/runtime/sections/index.js +1 -1
- package/dist/application-spec/parse-application-files/categorize/categorize-files.d.ts +3 -1
- package/dist/application-spec/parse-application-files/categorize/categorize-files.js +1 -1
- package/dist/application-spec/parse-application-files/merge/index.d.ts +1 -0
- package/dist/application-spec/parse-application-files/merge/index.js +1 -1
- package/dist/application-spec/parse-application-files/merge/merged-actions.d.ts +11 -0
- package/dist/application-spec/parse-application-files/merge/merged-actions.js +1 -0
- package/dist/application-spec/parse-application-files/merge/merged-spec.d.ts +2 -0
- package/dist/application-spec/parse-application-files/merge/merged-spec.js +1 -1
- package/dist/application-spec/parse-application-files/raw-spec/index.d.ts +1 -0
- package/dist/application-spec/parse-application-files/raw-spec/index.js +1 -1
- package/dist/application-spec/parse-application-files/raw-spec/raw-actions.d.ts +18 -0
- package/dist/application-spec/parse-application-files/raw-spec/raw-actions.js +1 -0
- package/dist/application-spec/parse-application-files/raw-spec/raw-assistant.d.ts +14 -2
- package/dist/application-spec/parse-application-files/raw-spec/raw-assistant.js +1 -1
- package/dist/application-spec/parse-application-files/raw-spec/raw-spec-file.d.ts +2 -0
- package/dist/application-spec/parse-application-files/raw-spec/raw-spec-file.js +1 -1
- package/dist/application-spec/parse-application-files/resolve/resolve-import-modules.js +1 -1
- package/dist/application-spec/parse-application-files/spec/application/application-spec.js +1 -1
- package/dist/application-spec/parse-application-files/spec/application/configurator-spec/configurator-spec.d.ts +4 -2
- package/dist/application-spec/parse-application-files/spec/application/configurator-spec/configurator-spec.js +1 -1
- package/dist/application-spec/parse-application-files/spec/common/index.d.ts +1 -0
- package/dist/application-spec/parse-application-files/spec/common/index.js +1 -1
- package/dist/application-spec/parse-application-files/spec/common/schema-ref-resolver.d.ts +23 -0
- package/dist/application-spec/parse-application-files/spec/common/schema-ref-resolver.js +1 -0
- package/dist/application-spec/parse-application-files/spec/model/names/action-name.d.ts +10 -0
- package/dist/application-spec/parse-application-files/spec/model/names/action-name.js +1 -0
- package/dist/application-spec/parse-application-files/spec/model/names/index.d.ts +1 -0
- package/dist/application-spec/parse-application-files/spec/model/names/index.js +1 -1
- package/dist/application-spec/parse-application-files/spec/sections/actions.d.ts +35 -0
- package/dist/application-spec/parse-application-files/spec/sections/actions.js +1 -0
- package/dist/application-spec/parse-application-files/spec/sections/assistant/assistant-field-type.d.ts +3 -14
- package/dist/application-spec/parse-application-files/spec/sections/assistant/assistant-field-type.js +1 -1
- package/dist/application-spec/parse-application-files/spec/sections/assistant/assistant-schema.d.ts +12 -3
- package/dist/application-spec/parse-application-files/spec/sections/assistant/assistant-schema.js +1 -1
- package/dist/application-spec/parse-application-files/spec/sections/assistant/assistant.d.ts +5 -3
- package/dist/application-spec/parse-application-files/spec/sections/index.d.ts +1 -0
- package/dist/application-spec/parse-application-files/spec/sections/index.js +1 -1
- package/dist/configurator/application-runtime/extensions/configurator-extension-systems.d.ts +2 -1
- package/dist/configurator/application-runtime/extensions/configurator-extension-systems.js +1 -1
- package/dist/configurator/application-runtime/extensions/selectors.d.ts +2 -1
- package/dist/configurator/application-runtime/extensions/selectors.js +1 -1
- package/dist/configurator/application-runtime/extensions/systems/assistant-system/assistant-system.d.ts +35 -0
- package/dist/configurator/application-runtime/extensions/systems/assistant-system/assistant-system.js +1 -0
- package/dist/configurator/{assistant → application-runtime/extensions/systems/assistant-system}/browser-details.d.ts +1 -1
- package/dist/configurator/application-runtime/extensions/systems/assistant-system/browser-details.js +1 -0
- package/dist/configurator/{assistant → application-runtime/extensions/systems/assistant-system}/graphql-tools.d.ts +13 -14
- package/dist/configurator/application-runtime/extensions/systems/assistant-system/graphql-tools.js +1 -0
- package/dist/configurator/application-runtime/extensions/systems/graphql-system/graphql-system.js +1 -1
- package/dist/configurator/application-runtime/extensions/systems/index.d.ts +1 -0
- package/dist/configurator/application-runtime/extensions/systems/index.js +1 -1
- package/dist/configurator/assistant/use-assistant-chat.js +1 -1
- package/dist/docs/index.json +12 -2
- package/dist/docs/other-features/domain-actions.mdx +418 -0
- package/dist/docs/phoenix/admin.mdx +2 -2
- package/dist/docs/phoenix/best-practices.mdx +1 -0
- package/dist/docs/phoenix/finalization.mdx +1 -1
- package/dist/docs/phoenix/integration/headless-mode-external.mdx +5 -5
- package/dist/docs/phoenix/integration/widget-mode-external.mdx +5 -5
- package/dist/docs/phoenix/phoenix-cli.mdx +59 -19
- package/dist/docs/phoenix/project-structure.mdx +4 -1
- package/dist/docs/phoenix/sdk-builder-workflow.mdx +5 -4
- package/dist/domain/actions/action-factory.d.ts +10 -0
- package/dist/domain/actions/action-factory.js +1 -0
- package/dist/domain/actions/prepare-action-implementations.d.ts +15 -0
- package/dist/domain/actions/prepare-action-implementations.js +5 -0
- package/dist/domain/application/application-config.d.ts +3 -1
- package/dist/domain/application/assistant-mutations.d.ts +15 -14
- package/dist/domain/application/assistant-mutations.js +1 -1
- package/dist/domain/core/action.d.ts +67 -0
- package/dist/domain/core/action.js +1 -0
- package/dist/domain/core/domain-factory.d.ts +4 -0
- package/dist/domain/core/index.d.ts +1 -0
- package/dist/domain/domain-builder.d.ts +7 -0
- package/dist/domain/domain-builder.js +1 -1
- package/dist/domain/domain-context/action-system/action-system.d.ts +40 -0
- package/dist/domain/domain-context/action-system/action-system.js +1 -0
- package/dist/domain/domain-context/domain-context-systems.d.ts +5 -2
- package/dist/domain/domain-context/index.d.ts +1 -0
- package/dist/domain/domain-context/index.js +1 -1
- package/dist/domain/domain-runtime/domain-context/domain-context.js +1 -1
- package/dist/domain/domain-runtime/domain-context/selectors.d.ts +4 -0
- package/dist/domain/domain-runtime/domain-context/selectors.js +1 -1
- package/dist/domain/domain-runtime/domain-runtime.d.ts +12 -0
- package/dist/domain/domain-runtime/spec/initialize.js +1 -1
- package/dist/domain/domain-runtime/spec/types.d.ts +15 -1
- package/dist/domain/index.d.ts +2 -0
- package/dist/domain/index.js +1 -1
- package/dist/domain/mocks/create-mock-domain-runtime.d.ts +6 -0
- package/dist/editor/domain-editors/DomainSpecContext.js +1 -1
- package/dist/editor/domain-editors/apply-spec-update.js +1 -1
- package/dist/editor/domain-editors/use-implementation-files.d.ts +7 -3
- package/dist/editor/domain-editors/use-implementation-files.js +1 -1
- package/dist/phoenix/application-spec/generate-assistant-prompt.d.ts +2 -2
- package/dist/phoenix/application-spec/generate-assistant-prompt.js +1 -1
- package/dist/phoenix/cli.js +1 -1
- package/dist/phoenix/commands/build.d.ts +5 -0
- package/dist/phoenix/commands/build.js +1 -1
- package/dist/phoenix/commands/feedback.d.ts +2 -1
- package/dist/phoenix/commands/feedback.js +1 -1
- package/dist/phoenix/commands/login.d.ts +24 -6
- package/dist/phoenix/commands/login.js +2 -2
- package/dist/phoenix/services/index.d.ts +1 -0
- package/dist/phoenix/services/index.js +1 -1
- package/dist/phoenix/services/phx-banner-plugin.d.ts +32 -0
- package/dist/phoenix/services/phx-banner-plugin.js +1 -0
- package/dist/phoenix/services/phx-licenses-plugin.d.ts +55 -0
- package/dist/phoenix/services/phx-licenses-plugin.js +8 -0
- package/dist/phoenix/services/vite-config.d.ts +2 -0
- package/dist/phoenix/services/vite-config.js +1 -1
- package/dist/phoenix/utils/index.d.ts +1 -0
- package/dist/phoenix/utils/index.js +1 -1
- package/dist/phoenix/utils/read-git-commit.d.ts +14 -0
- package/dist/phoenix/utils/read-git-commit.js +1 -0
- package/dist/react-sdk/application-runtime/runtime/create-application-runtime.d.ts +12 -0
- package/dist/react-sdk/domain-context/common-hooks/use-domain-context.d.ts +3 -0
- package/package.json +3 -3
- package/dist/configurator/assistant/browser-details.js +0 -1
- package/dist/configurator/assistant/graphql-tools.js +0 -1
|
@@ -2,6 +2,7 @@ import { Branded } from '@salsita-ai/common/utils';
|
|
|
2
2
|
import type { ImportedTransformer } from '#package/domain';
|
|
3
3
|
import type { RuntimeReferenceStore } from '../../../caching/index.js';
|
|
4
4
|
import type { ApplicationSpec } from '../../../parse-application-files/index.js';
|
|
5
|
+
import { ActionsRuntime } from '../sections/actions-runtime.js';
|
|
5
6
|
import { AssistantRuntime } from '../sections/assistant-runtime.js';
|
|
6
7
|
import { ComponentOptics } from '../sections/component-optic.js';
|
|
7
8
|
import { type ExpressionImplementations, ExpressionRuntime, type InvariantImplementations, type MissingExpression } from '../sections/expression-runtime.js';
|
|
@@ -20,6 +21,7 @@ export type ConfiguratorRuntime = Branded<'ConfiguratorRuntime', {
|
|
|
20
21
|
readonly themeRuntime: ThemeRuntime;
|
|
21
22
|
readonly transformersRuntime: TransformersRuntime;
|
|
22
23
|
readonly assistantRuntime: AssistantRuntime;
|
|
24
|
+
readonly actionsRuntime: ActionsRuntime;
|
|
23
25
|
}>;
|
|
24
26
|
export type ConfiguratorRuntimeResult = {
|
|
25
27
|
readonly ok: true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Branded as t}from"@salsita-ai/common/utils";import{AssistantRuntime as e}from"../sections/assistant-runtime.js";import{ComponentOptics as
|
|
1
|
+
import{Branded as t}from"@salsita-ai/common/utils";import{ActionsRuntime as o}from"../sections/actions-runtime.js";import{AssistantRuntime as e}from"../sections/assistant-runtime.js";import{ComponentOptics as r}from"../sections/component-optic.js";import{ExpressionRuntime as s}from"../sections/expression-runtime.js";import{PresetRuntime as i}from"../sections/preset-runtime.js";import{ThemeRuntime as n}from"../sections/theme-runtime.js";import{TransformersRuntime as m}from"../sections/transformers-runtime.js";import{ConfiguratorModelRuntime as u}from"./configurator-model-runtime.js";import{ConfiguratorStatesRuntime as c}from"./states-runtime.js";export const ConfiguratorRuntime=(p,a,f,g,R)=>{let j=u(p.configurator,a),x=s(p.configurator,a,f,"configuratorExpressionRuntime",R);return x.ok?{ok:!0,runtime:t({modelRuntime:j,componentOptics:r(a,{components:p.configurator.components,referenceScope:"configuratorRuntime/componentOptics",modelRuntime:j}),presetRuntime:i(a,{referenceScope:"configuratorRuntime/presetRuntime",presets:p.configurator.presets.presets}),statesRuntime:c(p,a),expressionRuntime:x.runtime,themeRuntime:n(p,a),transformersRuntime:m(p,a,g),assistantRuntime:e(p,a),actionsRuntime:o(p.configurator.actions,a)})}:{ok:!1,missingExpressions:x.missing}};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Branded } from '@salsita-ai/common/utils';
|
|
2
|
+
import type { ActionDefinitions } from '#package/domain';
|
|
3
|
+
import type { RuntimeReferenceStore } from '../../../caching/index.js';
|
|
4
|
+
import type { Actions } from '../../../parse-application-files/index.js';
|
|
5
|
+
/**
|
|
6
|
+
* The declared actions as the runtime spec slice holds them, with change tracking: the definitions
|
|
7
|
+
* are rebuilt only when their declaration changes, so a hot reload of an unrelated section keeps
|
|
8
|
+
* the action system's compiled validators.
|
|
9
|
+
*/
|
|
10
|
+
export type ActionsRuntime = Branded<'ActionsRuntime', {
|
|
11
|
+
readonly definitions: ActionDefinitions;
|
|
12
|
+
readonly changed: boolean;
|
|
13
|
+
}>;
|
|
14
|
+
export declare const ActionsRuntime: (actions: Actions, referenceStore: RuntimeReferenceStore) => ActionsRuntime;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import i from"lodash-es/isEqual.js";import{Branded as e}from"@salsita-ai/common/utils";export const ActionsRuntime=(t,n)=>{let o=n.createBuilder("configuratorRuntime/actions",{build:i=>i.definition,getKey:i=>i.definition.name,compare:(e,t)=>i(e.definition,t.definition)}),a=!1,r=new Set,d={};for(let i of t.values()){let e={definition:{name:String(i.name),...void 0===i.description?{}:{description:i.description},params:i.paramsSchema}},t=o.build(e);t.changed&&(a=!0),r.add(o.getKey(e)),d[t.output.name]=t.output}return o.cleanup(r)&&(a=!0),e({definitions:d,changed:a})};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export{AssistantRuntime}from"./assistant-runtime.js";export{ComponentOptics}from"./component-optic.js";export{DataRuntime}from"./data-runtime.js";export{ExpressionRuntime}from"./expression-runtime.js";export{PresetRuntime}from"./preset-runtime.js";export{ThemeRuntime}from"./theme-runtime.js";export{TransformersRuntime}from"./transformers-runtime.js";export{evaluateStaticMemoEvalPlan,generateMemoEvalPlanRuntime}from"./generate-memo-eval-plan-runtime.js";export{evaluateReflectionConstants,findReflectionConstants}from"./reflection-constants-runtime.js";
|
|
1
|
+
export{ActionsRuntime}from"./actions-runtime.js";export{AssistantRuntime}from"./assistant-runtime.js";export{ComponentOptics}from"./component-optic.js";export{DataRuntime}from"./data-runtime.js";export{ExpressionRuntime}from"./expression-runtime.js";export{PresetRuntime}from"./preset-runtime.js";export{ThemeRuntime}from"./theme-runtime.js";export{TransformersRuntime}from"./transformers-runtime.js";export{evaluateStaticMemoEvalPlan,generateMemoEvalPlanRuntime}from"./generate-memo-eval-plan-runtime.js";export{evaluateReflectionConstants,findReflectionConstants}from"./reflection-constants-runtime.js";
|
|
@@ -3,7 +3,7 @@ import { type RuntimeReferenceStore } from '../../caching/index.js';
|
|
|
3
3
|
import type { ParseContext, RawProjectFiles, TextFile } from '../../core/index.js';
|
|
4
4
|
import { type ModuleAnalysis, type ModuleAnalyzer, type WebhookMembership } from './module-analysis.js';
|
|
5
5
|
/** Known file categories used for path-based sorting. */
|
|
6
|
-
export type FileCategory = 'spec' | 'expressions' | 'handlers' | 'elements' | 'transformers' | 'components' | 'invariants' | 'migrations' | 'adminMigrations' | 'adminExpressions' | 'adminInvariants' | 'adminComponents' | 'adminElements' | 'webhooks' | 'locales' | 'mockTemplates' | 'projectFiles' | 'customCode';
|
|
6
|
+
export type FileCategory = 'spec' | 'expressions' | 'actions' | 'handlers' | 'elements' | 'transformers' | 'components' | 'invariants' | 'migrations' | 'adminMigrations' | 'adminExpressions' | 'adminInvariants' | 'adminComponents' | 'adminElements' | 'webhooks' | 'locales' | 'mockTemplates' | 'projectFiles' | 'customCode';
|
|
7
7
|
/**
|
|
8
8
|
* A text file categorized by path pattern, with dep-aware change tracking.
|
|
9
9
|
*
|
|
@@ -32,6 +32,8 @@ export type CategorizedFiles = Branded<'CategorizedFiles', {
|
|
|
32
32
|
readonly specChanged: boolean;
|
|
33
33
|
readonly expressions: readonly CategorizedFile[];
|
|
34
34
|
readonly expressionsChanged: boolean;
|
|
35
|
+
readonly actions: readonly CategorizedFile[];
|
|
36
|
+
readonly actionsChanged: boolean;
|
|
35
37
|
readonly handlers: readonly CategorizedFile[];
|
|
36
38
|
readonly handlersChanged: boolean;
|
|
37
39
|
readonly elements: readonly CategorizedFile[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import e from"lodash-es/isEqual.js";import{Branded as n}from"@salsita-ai/common/utils";import{computeFileDepHashes as s}from"../../caching/index.js";import{DiagnosticCode as o,diagnosticMessages as a}from"../../errors/index.js";import{findWebhookHandlerRegistration as i}from"./module-analysis.js";import{findWebhookSafetyViolation as t}from"./webhook-safety.js";export const buildProjectFileIndex=e=>new Map([...e.spec,...e.expressions,...e.handlers,...e.elements,...e.transformers,...e.components,...e.invariants,...e.migrations,...e.adminMigrations,...e.adminExpressions,...e.adminInvariants,...e.adminComponents,...e.adminElements,...e.webhooks,...e.locales,...e.mockTemplates,...e.projectFiles,...e.customCode].map(e=>[e.file.name,e]));let r=e=>/\/_[^/]+\//.test(e),m=[{path:"spec/",key:"spec"},{path:"src/admin/expressions/",key:"adminExpressions"},{path:"src/admin/invariants/",key:"adminInvariants"},{path:"src/admin/components/",key:"adminComponents"},{path:"src/admin/elements/",key:"adminElements"},{path:"src/admin/migrations/",key:"adminMigrations"},{path:"src/expressions/",key:"expressions"},{path:"src/handlers/",key:"handlers"},{path:"src/elements/",key:"elements"},{path:"src/transformers/",key:"transformers"},{path:"src/components/",key:"components"},{path:"src/invariants/",key:"invariants"},{path:"src/migrations/",key:"migrations"},{path:"src/webhooks/",key:"webhooks"},{path:"src/locales/",key:"locales"},{path:"mocks/",key:"mockTemplates"}],l=new Set(["package.json",".gitignore","CLAUDE.md",".cursor/rules/phoenix.mdc"]),d=new Set(["migrations","adminMigrations"]),
|
|
1
|
+
import e from"lodash-es/isEqual.js";import{Branded as n}from"@salsita-ai/common/utils";import{computeFileDepHashes as s}from"../../caching/index.js";import{DiagnosticCode as o,diagnosticMessages as a}from"../../errors/index.js";import{findWebhookHandlerRegistration as i}from"./module-analysis.js";import{findWebhookSafetyViolation as t}from"./webhook-safety.js";export const buildProjectFileIndex=e=>new Map([...e.spec,...e.expressions,...e.actions,...e.handlers,...e.elements,...e.transformers,...e.components,...e.invariants,...e.migrations,...e.adminMigrations,...e.adminExpressions,...e.adminInvariants,...e.adminComponents,...e.adminElements,...e.webhooks,...e.locales,...e.mockTemplates,...e.projectFiles,...e.customCode].map(e=>[e.file.name,e]));let r=e=>/\/_[^/]+\//.test(e),m=[{path:"spec/",key:"spec"},{path:"src/admin/expressions/",key:"adminExpressions"},{path:"src/admin/invariants/",key:"adminInvariants"},{path:"src/admin/components/",key:"adminComponents"},{path:"src/admin/elements/",key:"adminElements"},{path:"src/admin/migrations/",key:"adminMigrations"},{path:"src/expressions/",key:"expressions"},{path:"src/actions/",key:"actions"},{path:"src/handlers/",key:"handlers"},{path:"src/elements/",key:"elements"},{path:"src/transformers/",key:"transformers"},{path:"src/components/",key:"components"},{path:"src/invariants/",key:"invariants"},{path:"src/migrations/",key:"migrations"},{path:"src/webhooks/",key:"webhooks"},{path:"src/locales/",key:"locales"},{path:"mocks/",key:"mockTemplates"}],l=new Set(["package.json",".gitignore","CLAUDE.md",".cursor/rules/phoenix.mdc"]),d=new Set(["migrations","adminMigrations"]),c=m.filter(({path:e,key:n})=>e.startsWith("src/")&&d.has(n)),p=(e,n)=>{let s=e.slice(n.length).split("/");return!(s.length<=1)&&s.slice(0,-1).some(e=>!e.startsWith("_"))},h=/\.(ts|tsx|js|jsx)$/,f=(e,n)=>{if("components"===e||"adminComponents"===e)return n.hasUseWebhookDirective?{membership:"pinned",logSuffix:"webhook ('use webhook' directive)"}:{membership:"frontend",logSuffix:"frontend only (no 'use webhook' directive)"};if("handlers"===e){let e=i(n);return void 0!==e?{membership:"named-handler",logSuffix:`webhook (the ${e} registration)`}:n.hasUseWebhookDirective?{membership:"pinned",logSuffix:"webhook ('use webhook' directive)"}:{membership:"frontend",logSuffix:"frontend only (not a named handler or pin)"}}};export const CategorizedFiles=(i,d,g,u)=>{let k={spec:[],expressions:[],actions:[],handlers:[],elements:[],transformers:[],components:[],invariants:[],migrations:[],adminMigrations:[],adminExpressions:[],adminInvariants:[],adminComponents:[],adminElements:[],webhooks:[],locales:[],mockTemplates:[],projectFiles:[],customCode:[]},b=[];for(let e of i.files){if("text"!==e.kind)continue;if(r(e.name)){k.customCode.push({file:e,category:"customCode"});continue}if(l.has(e.name)){k.projectFiles.push({file:e,category:"projectFiles"});continue}let n=!1;for(let{path:s,key:o}of m)if(e.name.startsWith(s)){k[o].push({file:e,category:o}),n=!0;break}n||b.push(e.name)}for(let e of b)e.startsWith("src/")&&g.error(o.UNKNOWN_SRC_PATH,a.UNKNOWN_SRC_PATH(e));for(let{path:e,key:n}of c)for(let s of k[n])p(s.file.name,e)&&g.error(o.INVALID_SUBDIRECTORY,a.INVALID_SUBDIRECTORY(s.file.name,e));if(k.webhooks.length>0&&!k.webhooks.some(e=>"src/webhooks/index.ts"===e.file.name)&&g.error(o.MISSING_WEBHOOK_INDEX,a.MISSING_WEBHOOK_INDEX()),g.hasErrors)return;let C=[];for(let e of Object.values(k))for(let n of e)C.push(n.file.name);let v=s(i,C),{analyzer:x,logger:y}=u,E=d.createBuilder("categorizedFiles/moduleAnalysis",{build:e=>{try{return{analysis:x(e.name,e.content)}}catch(e){return{error:e instanceof Error?e.message:String(e)}}},getKey:e=>e.name,compare:(e,n)=>e.content===n.content}),I=new Set,w=e=>{if(!h.test(e.name))return;I.add(e.name);let n=E.build({name:e.name,content:e.content}).output;return void 0!==n.error?void g.error(o.MODULE_ANALYSIS_FAILED,a[o.MODULE_ANALYSIS_FAILED](e.name,n.error)):n.analysis},S={},j={};for(let[e,s]of Object.entries(k)){let o=d.createBuilder(`categorizedFiles/${e}`,{build:e=>e,getKey:e=>e.name,compare:(e,n)=>e.depHash===n.depHash}),a=new Set;S[e]=s.map(e=>{let s=v[e.file.name]??{deps:[],hash:""},{changed:i}=o.build({name:e.file.name,depHash:s.hash});a.add(e.file.name);let t=w(e.file),r=void 0===t?void 0:f(e.category,t);return void 0!==r&&y.debug(`Webhook membership: ${e.file.name} -> ${r.logSuffix}`),n({file:e.file,category:e.category,deps:s.deps,depHash:s.hash,changed:i,analysis:t,webhookMembership:r?.membership})}),j[e]=o.cleanup(a)}E.cleanup(I);let _=(e,n)=>n.some(e=>e.changed)||!0===j[e],F=d.createBuilder("categorizedFiles/envs",{build:e=>e.envs,getKey:()=>"singleton",compare:(n,s)=>e(n.envs,s.envs)}).build({envs:i.envs}),M=n({spec:S.spec,specChanged:_("spec",S.spec),expressions:S.expressions,expressionsChanged:_("expressions",S.expressions),actions:S.actions,actionsChanged:_("actions",S.actions),handlers:S.handlers,handlersChanged:_("handlers",S.handlers),elements:S.elements,elementsChanged:_("elements",S.elements),transformers:S.transformers,transformersChanged:_("transformers",S.transformers),components:S.components,componentsChanged:_("components",S.components),invariants:S.invariants,invariantsChanged:_("invariants",S.invariants),migrations:S.migrations,migrationsChanged:_("migrations",S.migrations),adminMigrations:S.adminMigrations,adminMigrationsChanged:_("adminMigrations",S.adminMigrations),adminExpressions:S.adminExpressions,adminExpressionsChanged:_("adminExpressions",S.adminExpressions),adminInvariants:S.adminInvariants,adminInvariantsChanged:_("adminInvariants",S.adminInvariants),adminComponents:S.adminComponents,adminComponentsChanged:_("adminComponents",S.adminComponents),adminElements:S.adminElements,adminElementsChanged:_("adminElements",S.adminElements),webhooks:S.webhooks,webhooksChanged:_("webhooks",S.webhooks),locales:S.locales,localesChanged:_("locales",S.locales),mockTemplates:S.mockTemplates,mockTemplatesChanged:_("mockTemplates",S.mockTemplates),projectFiles:S.projectFiles,projectFilesChanged:_("projectFiles",S.projectFiles),customCode:S.customCode,customCodeChanged:_("customCode",S.customCode),envs:F.output,envsChanged:F.changed}),O=buildProjectFileIndex(M);for(let e of O.values()){if("pinned"!==e.webhookMembership&&"named-handler"!==e.webhookMembership)continue;let n=t(e,O);void 0!==n&&g.error(o.WEBHOOK_UNSAFE_IMPORT,a[o.WEBHOOK_UNSAFE_IMPORT](n.fileName,n.inclusionReason,n.importer,n.specifier))}return M};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export*from"./classified-spec-file.js";export*from"./merged-admin-components.js";export*from"./merged-admin-expressions.js";export*from"./merged-admin-invariants.js";export*from"./merged-admin-states.js";export*from"./merged-admin-model.js";export*from"./merged-components.js";export*from"./merged-configurator-states.js";export*from"./merged-defaults.js";export*from"./merged-model.js";export*from"./merged-admin-pages.js";export*from"./merged-admin-presets.js";export*from"./merged-admin-relations.js";export*from"./merged-assistant.js";export*from"./merged-budgets.js";export*from"./merged-data-schemas.js";export*from"./merged-data-spec.js";export*from"./merged-expressions.js";export*from"./merged-presets.js";export*from"./merged-relations.js";export*from"./merged-spec.js";export*from"./merged-theme.js";export*from"./merged-ui.js";export*from"./merged-transformers.js";export*from"./merged-app-metadata.js";export*from"./merged-infra.js";export*from"./merged-invariants.js";export*from"./merged-chunks.js";
|
|
1
|
+
export*from"./classified-spec-file.js";export*from"./merged-actions.js";export*from"./merged-admin-components.js";export*from"./merged-admin-expressions.js";export*from"./merged-admin-invariants.js";export*from"./merged-admin-states.js";export*from"./merged-admin-model.js";export*from"./merged-components.js";export*from"./merged-configurator-states.js";export*from"./merged-defaults.js";export*from"./merged-model.js";export*from"./merged-admin-pages.js";export*from"./merged-admin-presets.js";export*from"./merged-admin-relations.js";export*from"./merged-assistant.js";export*from"./merged-budgets.js";export*from"./merged-data-schemas.js";export*from"./merged-data-spec.js";export*from"./merged-expressions.js";export*from"./merged-presets.js";export*from"./merged-relations.js";export*from"./merged-spec.js";export*from"./merged-theme.js";export*from"./merged-ui.js";export*from"./merged-transformers.js";export*from"./merged-app-metadata.js";export*from"./merged-infra.js";export*from"./merged-invariants.js";export*from"./merged-chunks.js";
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Branded } from '@salsita-ai/common/utils';
|
|
2
|
+
import type { ParseContext } from '../../core/index.js';
|
|
3
|
+
import type { RawActions } from '../raw-spec/index.js';
|
|
4
|
+
import type { ClassifiedSpecFile } from './classified-spec-file.js';
|
|
5
|
+
/**
|
|
6
|
+
* Merged actions from all spec files; an action name declared in two files is a merge conflict.
|
|
7
|
+
* Actions belong to the configurator domain, so an `actions` block in an admin spec file is reported
|
|
8
|
+
* rather than merged.
|
|
9
|
+
*/
|
|
10
|
+
export type MergedActions = Branded<'MergedActions', RawActions>;
|
|
11
|
+
export declare const MergedActions: (files: readonly ClassifiedSpecFile[], ctx: ParseContext) => MergedActions;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{Branded as e}from"@salsita-ai/common/utils";import{DiagnosticCode as n,diagnosticMessages as o}from"../../errors/index.js";export const MergedActions=(t,i)=>{let r={},a={};for(let e of t)if(e.content.actions){if(e.isAdmin){i.inFile(e.name).at("actions").error(n.ACTIONS_IN_ADMIN_FILE,o.ACTIONS_IN_ADMIN_FILE(e.name));continue}for(let[n,o]of Object.entries(e.content.actions)){let t=a[n];if(t){i.error("MERGE_CONFLICT",`Action "${n}" is declared in both "${t}" and "${e.name}". Each action can only be declared once. Keep one declaration and remove the other.`);continue}r[n]=o,a[n]=e.name}}return e(r)};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Branded } from '@salsita-ai/common/utils';
|
|
2
2
|
import type { ParseContext } from '../../core/index.js';
|
|
3
3
|
import type { ResolvedSpecFiles } from '../resolve/index.js';
|
|
4
|
+
import { MergedActions } from './merged-actions.js';
|
|
4
5
|
import { MergedAdminPages } from './merged-admin-pages.js';
|
|
5
6
|
import { MergedAdminStates } from './merged-admin-states.js';
|
|
6
7
|
import { MergedAppMetadata } from './merged-app-metadata.js';
|
|
@@ -31,6 +32,7 @@ export type MergedSpec = Branded<'MergedSpec', {
|
|
|
31
32
|
readonly adminPages: MergedAdminPages;
|
|
32
33
|
readonly expressions: MergedExpressions;
|
|
33
34
|
readonly adminExpressions: MergedExpressions;
|
|
35
|
+
readonly actions: MergedActions;
|
|
34
36
|
readonly invariants: MergedInvariants;
|
|
35
37
|
readonly adminInvariants: MergedInvariants;
|
|
36
38
|
readonly relations: MergedRelations;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Branded as e}from"@salsita-ai/common/utils";import{classifySpecFile as r}from"./classified-spec-file.js";import{
|
|
1
|
+
import{Branded as e}from"@salsita-ai/common/utils";import{classifySpecFile as r}from"./classified-spec-file.js";import{MergedActions as m}from"./merged-actions.js";import{MergedAdminComponents as o}from"./merged-admin-components.js";import{MergedAdminExpressions as s}from"./merged-admin-expressions.js";import{MergedAdminInvariants as t}from"./merged-admin-invariants.js";import{MergedAdminModel as i}from"./merged-admin-model.js";import{MergedAdminPages as d}from"./merged-admin-pages.js";import{MergedAdminPresets as p}from"./merged-admin-presets.js";import{MergedAdminRelations as a}from"./merged-admin-relations.js";import{MergedAdminStates as n}from"./merged-admin-states.js";import{MergedAppMetadata as g}from"./merged-app-metadata.js";import{MergedAssistant as f}from"./merged-assistant.js";import{MergedBudgets as j}from"./merged-budgets.js";import{MergedChunks as l}from"./merged-chunks.js";import{MergedComponents as c}from"./merged-components.js";import{MergedConfiguratorStates as M}from"./merged-configurator-states.js";import{MergedDataSchemas as S}from"./merged-data-schemas.js";import{MergedDataSpec as u}from"./merged-data-spec.js";import{MergedDefaults as h}from"./merged-defaults.js";import{MergedExpressions as A}from"./merged-expressions.js";import{MergedInfra as x}from"./merged-infra.js";import{MergedInvariants as k}from"./merged-invariants.js";import{MergedModel as v}from"./merged-model.js";import{MergedPresets as C}from"./merged-presets.js";import{MergedRelations as b}from"./merged-relations.js";import{MergedTheme as q}from"./merged-theme.js";import{MergedTransformers as w}from"./merged-transformers.js";import{MergedUi as y}from"./merged-ui.js";export const MergedSpec=(z,B)=>{let D=z.map(e=>r(e)),E=D.filter(e=>!e.isAdmin),F=D.filter(e=>e.isAdmin),G=B.startSpan("MergedModel","MergedSpec","merged-model.ts"),H=v(E,B);G();let I=B.startSpan("MergedAdminModel","MergedSpec","merged-admin-model.ts"),J=i(F,B);I();let K=B.startSpan("MergedComponents","MergedSpec","merged-components.ts"),L=c(E,B);K();let N=B.startSpan("MergedAdminComponents","MergedSpec","merged-admin-components.ts"),O=o(F,B);N();let P=C(E),Q=p(F,B),R=d(F,B),T=A(E,B),U=s(F,B),V=m(D,B),W=k(E,B),X=t(F,B),Y=b(E,B),Z=a(F,B),$=h(E,B),_=h(F,B),ee=S(D,B),er=u(D,B),em=M(E,B),eo=n(F,B),es=q(D,B),et=y(D,B),ei=w(D,B),ed=g(D,B),ep=x(D,B),ea=j(D,B);return e({model:H,adminModel:J,components:L,adminComponents:O,presets:P,adminPresets:Q,adminPages:R,expressions:T,adminExpressions:U,actions:V,invariants:W,adminInvariants:X,relations:Y,adminRelations:Z,defaults:$,adminDefaults:_,dataSchemas:ee,dataSpec:er,configuratorStates:em,adminStates:eo,theme:es,ui:et,transformers:ei,appMetadata:ed,infra:ep,budgets:ea,chunks:l(D,B),assistant:f(D,B)})};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export*from"./raw-admin-pages.js";export*from"./raw-acl.js";export*from"./raw-assistant.js";export*from"./raw-budgets.js";export*from"./raw-chunks.js";export*from"./raw-components.js";export*from"./raw-constants.js";export*from"./raw-data.js";export*from"./raw-defaults.js";export*from"./raw-env.js";export*from"./raw-expressions.js";export*from"./raw-invariants.js";export*from"./raw-model.js";export*from"./raw-mock-templates.js";export*from"./raw-presets.js";export*from"./raw-relations.js";export*from"./raw-resources.js";export*from"./raw-spec-file.js";export*from"./raw-states.js";export*from"./raw-transformers.js";export*from"./parse-raw-spec.js";
|
|
1
|
+
export*from"./raw-admin-pages.js";export*from"./raw-acl.js";export*from"./raw-actions.js";export*from"./raw-assistant.js";export*from"./raw-budgets.js";export*from"./raw-chunks.js";export*from"./raw-components.js";export*from"./raw-constants.js";export*from"./raw-data.js";export*from"./raw-defaults.js";export*from"./raw-env.js";export*from"./raw-expressions.js";export*from"./raw-invariants.js";export*from"./raw-model.js";export*from"./raw-mock-templates.js";export*from"./raw-presets.js";export*from"./raw-relations.js";export*from"./raw-resources.js";export*from"./raw-spec-file.js";export*from"./raw-states.js";export*from"./raw-transformers.js";export*from"./parse-raw-spec.js";
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { type EnhancedJsonSchemaType } from '../../core/enhanced-json-schema.js';
|
|
3
|
+
/**
|
|
4
|
+
* One action declared under the top-level `actions:` block: a domain operation the project
|
|
5
|
+
* implements in `src/actions/` and the application runs through the action system. `params` and
|
|
6
|
+
* `result` are maps of named enhanced JSON schemas; a `phx:DomainEntityId` param with `references`
|
|
7
|
+
* is typed by the referenced entity type or alias, and a `phx:$DomainEntity` result member with
|
|
8
|
+
* `references` is typed as the enhanced entity. The `description` of the action and of each param
|
|
9
|
+
* and result member documents it in the generated types; whoever exposes the action can reuse it.
|
|
10
|
+
*/
|
|
11
|
+
export interface RawActionEntry {
|
|
12
|
+
readonly description?: string;
|
|
13
|
+
readonly params: Readonly<Record<string, EnhancedJsonSchemaType>>;
|
|
14
|
+
readonly result: Readonly<Record<string, EnhancedJsonSchemaType>>;
|
|
15
|
+
}
|
|
16
|
+
/** Record of all action entries keyed by action name, produced by `rawSpecFileSchema` for the `actions:` block. */
|
|
17
|
+
export type RawActions = Readonly<Record<string, RawActionEntry>>;
|
|
18
|
+
export declare const rawActionsSchema: z.ZodType<RawActions, z.ZodTypeDef, unknown>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{z as e}from"zod";import{enhancedJsonSchema as r}from"../../core/enhanced-json-schema.js";let a=r=>e.string().regex(/^[A-Za-z][A-Za-z0-9_]*$/,`is not a valid ${r} name: use letters, digits and underscores, starting with a letter, e.g. "partId"`),t=e.object({description:e.string().optional(),params:e.record(a("parameter"),r,{required_error:"is required: declare the parameters of the action as a map of named schemas, empty when it takes none",invalid_type_error:"must be a map of parameter names to JSON schemas"}),result:e.record(a("result member"),r,{required_error:"is required: declare the result of the action as a map of named schemas",invalid_type_error:"must be a map of result member names to JSON schemas"})}).strict();export const rawActionsSchema=e.record(e.string(),t).readonly();
|
|
@@ -68,6 +68,16 @@ export interface RawAssistantRecipes {
|
|
|
68
68
|
readonly hints?: readonly AssistantHint[];
|
|
69
69
|
readonly groups: Readonly<Record<string, RawAssistantRecipeGroup | null>>;
|
|
70
70
|
}
|
|
71
|
+
/**
|
|
72
|
+
* One entry of the assistant `actions` map, keyed by the name of an action declared under the
|
|
73
|
+
* top-level `actions` block: it exposes the action as a `Mutation` field named `as` (the action name
|
|
74
|
+
* by default) with `description` (the action's own by default). An empty entry (`movePartBy:` in
|
|
75
|
+
* YAML) exposes the action with its defaults.
|
|
76
|
+
*/
|
|
77
|
+
export interface RawAssistantAction {
|
|
78
|
+
readonly description?: string;
|
|
79
|
+
readonly as?: string;
|
|
80
|
+
}
|
|
71
81
|
/**
|
|
72
82
|
* Experimental assistant manifest authored under the `assistant` root key. `entities` whitelists the
|
|
73
83
|
* stored fields the generated GraphQL schema exposes, keyed by entity type or alias name and then by
|
|
@@ -77,8 +87,9 @@ export interface RawAssistantRecipes {
|
|
|
77
87
|
* have to be exposed in `entities`. `childRecipes` names, per
|
|
78
88
|
* entity type or alias, the `childEntityRecipes` groups whose recipes the agent may list and add
|
|
79
89
|
* with `addChild`. `replaceRecipes` names, per entity type or alias, the `replaceEntityRecipes`
|
|
80
|
-
* groups whose recipes the agent may list and replace the entity by with `replaceEntity`.
|
|
81
|
-
* exposed without an
|
|
90
|
+
* groups whose recipes the agent may list and replace the entity by with `replaceEntity`. `actions`
|
|
91
|
+
* names the declared actions the agent may run as custom mutations. Nothing is exposed without an
|
|
92
|
+
* entry.
|
|
82
93
|
*
|
|
83
94
|
* `ai` and `instructions` are for the server only: the provider, model tier and reasoning level the
|
|
84
95
|
* deployment's assistant runs with, and the integrator's own guidance for it, appended to the system
|
|
@@ -90,6 +101,7 @@ export interface RawAssistant {
|
|
|
90
101
|
readonly writable?: Readonly<Record<string, Readonly<Record<string, RawAssistantWritableField | null>>>>;
|
|
91
102
|
readonly childRecipes?: Readonly<Record<string, RawAssistantRecipes>>;
|
|
92
103
|
readonly replaceRecipes?: Readonly<Record<string, RawAssistantRecipes>>;
|
|
104
|
+
readonly actions?: Readonly<Record<string, RawAssistantAction | null>>;
|
|
93
105
|
readonly instructions?: string;
|
|
94
106
|
readonly ai: AssistantAiSettings;
|
|
95
107
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{z as t}from"zod";import{ASSISTANT_AI_PROVIDERS as e,ASSISTANT_MODEL_TIERS as o,ASSISTANT_REASONING_LEVELS as i}from"@salsita-ai/contracts/assistant";export const ASSISTANT_OPTION_COMPONENT_TYPES=["materialSwatch","attributeSelection","distanceDimensionSelect"];export const ASSISTANT_HINTS=["sameForAllInstances","constantDuringSession"];let n=t.string().regex(/^(?!__)[_A-Za-z][_0-9A-Za-z]*$/,'must be a GraphQL name: letters, digits and "_", not starting with a digit or "__"'),r=e=>t.enum(e,{errorMap:()=>({message:`must be one of: ${e.join(", ")}`})}),s=t.object({description:t.string().optional(),as:n.optional()}).strict(),a=t.array(r(ASSISTANT_HINTS)),c=t.object({options:t.object({componentType:r(ASSISTANT_OPTION_COMPONENT_TYPES),instanceName:t.string().min(1,"must not be empty; name the component instance that holds the choices"),as:n.optional(),validate:t.boolean().optional(),allowDryRuns:t.boolean().optional(),hints:a.optional()}).strict().optional()}).strict(),l=t.object({as:t.string().trim().min(1,"must not be empty; remove the key to use the instance name").optional(),description:t.string().optional(),allowDryRuns:t.boolean().optional()}).strict(),p=e=>t.object({hints:a.optional(),groups:t.record(t.string(),l.nullable(),{required_error:`is required: the recipe groups of the type go under "groups", keyed by the instance name of a "${e}" component`})}).strict(),m=`is required: declare provider (${e.join(", ")}), model (${o.join(", ")}) and reasoning (${i.join(", ")})`,
|
|
1
|
+
import{z as t}from"zod";import{ASSISTANT_AI_PROVIDERS as e,ASSISTANT_MODEL_TIERS as o,ASSISTANT_REASONING_LEVELS as i}from"@salsita-ai/contracts/assistant";export const ASSISTANT_OPTION_COMPONENT_TYPES=["materialSwatch","attributeSelection","distanceDimensionSelect"];export const ASSISTANT_HINTS=["sameForAllInstances","constantDuringSession"];let n=t.string().regex(/^(?!__)[_A-Za-z][_0-9A-Za-z]*$/,'must be a GraphQL name: letters, digits and "_", not starting with a digit or "__"'),r=e=>t.enum(e,{errorMap:()=>({message:`must be one of: ${e.join(", ")}`})}),s=t.object({description:t.string().optional(),as:n.optional()}).strict(),a=t.array(r(ASSISTANT_HINTS)),c=t.object({options:t.object({componentType:r(ASSISTANT_OPTION_COMPONENT_TYPES),instanceName:t.string().min(1,"must not be empty; name the component instance that holds the choices"),as:n.optional(),validate:t.boolean().optional(),allowDryRuns:t.boolean().optional(),hints:a.optional()}).strict().optional()}).strict(),l=t.object({as:t.string().trim().min(1,"must not be empty; remove the key to use the instance name").optional(),description:t.string().optional(),allowDryRuns:t.boolean().optional()}).strict(),p=e=>t.object({hints:a.optional(),groups:t.record(t.string(),l.nullable(),{required_error:`is required: the recipe groups of the type go under "groups", keyed by the instance name of a "${e}" component`})}).strict(),d=t.object({description:t.string().optional(),as:n.optional()}).strict(),m=`is required: declare provider (${e.join(", ")}), model (${o.join(", ")}) and reasoning (${i.join(", ")})`,g=t.object({provider:r(e),model:r(o),reasoning:r(i)},{required_error:m,invalid_type_error:m}).strict();export const rawAssistantSchema=t.object({entities:t.record(t.string(),t.record(t.string(),s.nullable())).optional(),deletable:t.record(t.string(),t.object({}).strict().nullable()).optional(),writable:t.record(t.string(),t.record(t.string(),c.nullable())).optional(),childRecipes:t.record(t.string(),p("childEntityRecipes")).optional(),replaceRecipes:t.record(t.string(),p("replaceEntityRecipes")).optional(),actions:t.record(t.string(),d.nullable()).optional(),instructions:t.string().trim().min(1,"must not be empty; remove the key when there are no instructions").optional(),ai:g}).strict();
|
|
@@ -2,6 +2,7 @@ import { Branded } from '@salsita-ai/common/utils';
|
|
|
2
2
|
import { type EnhancedJsonObjectSchemaType, type ParseContext } from '../../core/index.js';
|
|
3
3
|
import type { ParsedYamlFile } from './parse-yaml-spec-file.js';
|
|
4
4
|
import { type RawAcl } from './raw-acl.js';
|
|
5
|
+
import { type RawActions } from './raw-actions.js';
|
|
5
6
|
import { type RawAdminPages } from './raw-admin-pages.js';
|
|
6
7
|
import { type RawAssistant } from './raw-assistant.js';
|
|
7
8
|
import { type RawBudgets } from './raw-budgets.js';
|
|
@@ -24,6 +25,7 @@ export interface RawSpecContent {
|
|
|
24
25
|
readonly presets?: RawPresets;
|
|
25
26
|
readonly $data?: RawDataSpec;
|
|
26
27
|
readonly expressions?: RawExpressions;
|
|
28
|
+
readonly actions?: RawActions;
|
|
27
29
|
readonly invariants?: RawInvariants;
|
|
28
30
|
readonly relations?: RawRelations;
|
|
29
31
|
readonly defaults?: RawDefaults;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{z as o}from"zod";import{Branded as a}from"@salsita-ai/common/utils";import{enhancedJsonObjectSchema as t,validateNoLegacyCodeRef as e}from"../../core/index.js";import{DiagnosticCode as n,diagnosticMessages as
|
|
1
|
+
import{z as o}from"zod";import{Branded as a}from"@salsita-ai/common/utils";import{enhancedJsonObjectSchema as t,validateNoLegacyCodeRef as e}from"../../core/index.js";import{DiagnosticCode as n,diagnosticMessages as i}from"../../errors/index.js";import{rawAclSchema as r}from"./raw-acl.js";import{rawActionsSchema as s}from"./raw-actions.js";import{rawAdminPagesSchema as l}from"./raw-admin-pages.js";import{rawAssistantSchema as p}from"./raw-assistant.js";import{rawBudgetsSchema as m}from"./raw-budgets.js";import{rawChunksSchema as c}from"./raw-chunks.js";import{rawComponentsSchema as f}from"./raw-components.js";import{rawConstantsSchema as d}from"./raw-constants.js";import{rawDataSpecSchema as u}from"./raw-data.js";import{rawDefaultsSchema as j}from"./raw-defaults.js";import{rawEnvSchema as w}from"./raw-env.js";import{rawExpressionsSchema as b}from"./raw-expressions.js";import{rawInvariantsSchema as g}from"./raw-invariants.js";import{rawModelSchema as S}from"./raw-model.js";import{rawPresetsSchema as D}from"./raw-presets.js";import{rawRelationsSchema as h}from"./raw-relations.js";import{rawResourcesConfigSchema as v,rawResourcesSchema as O}from"./raw-resources.js";import{rawStateValuesSchema as E}from"./raw-states.js";import{rawTransformersSchema as R}from"./raw-transformers.js";export const DATA_SCHEMA_KEYS=["publishedData","sessionData","frontendData","backendData","finalizeData","prefetchedFinalizeData","finalizeResult","callbackData"];let k=o.object({$admin:o.boolean().optional(),model:S.optional(),components:f.optional(),presets:D.optional(),$data:u.optional(),expressions:b.optional(),actions:s.optional(),invariants:g.optional(),constants:d.optional(),relations:h.optional(),defaults:j.optional(),publishedData:t.optional(),sessionData:t.optional(),frontendData:t.optional(),backendData:t.optional(),finalizeData:t.optional(),prefetchedFinalizeData:t.optional(),finalizeResult:t.optional(),callbackData:t.optional(),navigationStates:E.optional(),viewStates:E.optional(),toolStates:E.optional(),exportStates:E.optional(),themePreset:o.string().optional(),themeOptions:o.record(o.unknown()).optional(),preview:o.enum(["always","never","auto","hide"]).optional(),alwaysExpand:o.boolean().optional(),availableLocales:o.array(o.string()).optional(),textLanguages:o.array(o.string()).optional(),transformers:R.optional(),project:o.string().regex(/^[a-z0-9-]{3,}$/,"must be a project slug (lowercase letters, digits and dashes, at least 3) or `default`").optional(),applicationVersion:o.string().optional(),workspace:o.boolean().optional(),webComponentTag:o.string().optional(),pageTitle:o.string().optional(),useAuthHook:o.boolean().optional(),useClerk:o.boolean().optional(),enableAdminRelease:o.boolean().optional(),jsonSchemaValidator:o.enum(["ajv","csp-compatible"]).optional(),gltfDecoder:o.enum(["js","wasm"]).optional(),appLoader:o.enum(["legacy","universal"]).optional(),collectFinalizeData:o.boolean().optional(),env:w.optional(),acl:r.optional(),resources:O.optional(),resourcesConfig:v.optional(),budgets:m.optional(),chunks:c.optional(),assistant:p.optional(),$adminPages:l.optional()}).strict();export const parseRawSpecFile=(o,t)=>{e(o.content,t);let r=k.safeParse(o.content);if(!r.success){for(let o of r.error.issues)t.error(n.SCHEMA_PARSE_ERROR,i.SCHEMA_PARSE_ERROR(o.path.join("."),o.message));return}let{constants:s,...l}=r.data,p=((o,a)=>{let t=Object.fromEntries(Object.entries(o.expressions??{}).map(([o,a])=>[o,{...a}]));if(void 0===o.constants)return Object.keys(t).length>0?t:void 0;for(let[e,r]of Object.entries(o.constants))for(let[o,s]of(t[e]||(t[e]={}),Object.entries(r))){if(void 0!==t[e][o]){a.at("constants",e,o).error(n.CONSTANTS_EXPRESSION_CONFLICT,i[n.CONSTANTS_EXPRESSION_CONFLICT](e,o));continue}t[e][o]={kind:"value",constant:!0,value:s,schema:{}}}return Object.keys(t).length>0?t:void 0})(r.data,t);return a({name:o.name,content:{...l,expressions:p}})};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{mapSchema as e,resolveProjectFileImport as t,resolveProjectPath as r}from"../../core/index.js";import{DiagnosticCode as o,diagnosticMessages as s}from"../../errors/index.js";import{DATA_SCHEMA_KEYS as
|
|
1
|
+
import{mapSchema as e,resolveProjectFileImport as t,resolveProjectPath as r}from"../../core/index.js";import{DiagnosticCode as o,diagnosticMessages as s}from"../../errors/index.js";import{DATA_SCHEMA_KEYS as n}from"../raw-spec/index.js";let m=(n,m,a,i)=>e(n,(e,n)=>e.import?{...e,import:e.import.map((e,p)=>{if(!e.module.startsWith("."))return e;let c=r(m,e.module),O=i.at(...n,"import",String(p),"module");c.escapedProjectRoot?O.warning(o.IMPORT_MODULE_OUTSIDE_PROJECT,s[o.IMPORT_MODULE_OUTSIDE_PROJECT](e.module,c.path)):t(m,e.module,a)||O.error(o.IMPORT_MODULE_NOT_FOUND,s[o.IMPORT_MODULE_NOT_FOUND](e.module,c.path));let l=c.path.startsWith(".")?c.path:`./${c.path}`;return{...e,module:l}})}:e);export const resolveImportModules=(e,t,r)=>{let o=e.content.model?Object.fromEntries(Object.entries(e.content.model).map(([o,s])=>[o,{...s,...s.commonTypes?{commonTypes:Object.fromEntries(Object.entries(s.commonTypes).map(([s,n])=>[s,m(n,e.name,t,r.at("model",o,"commonTypes",s))]))}:{},...s.shapes?{shapes:Object.fromEntries(Object.entries(s.shapes).map(([s,n])=>[s,Object.fromEntries(Object.entries(n).map(([n,a])=>[n,m(a,e.name,t,r.at("model",o,"shapes",s,n))]))]))}:{}}])):void 0,s=e.content.expressions?Object.fromEntries(Object.entries(e.content.expressions).map(([o,s])=>[o,Object.fromEntries(Object.entries(s).map(([s,n])=>[s,{...n,schema:m(n.schema,e.name,t,r.at("expressions",o,s))}]))])):void 0,a=e.content.actions?Object.fromEntries(Object.entries(e.content.actions).map(([o,s])=>{let n=(s,n)=>Object.fromEntries(Object.entries(s).map(([s,a])=>[s,m(a,e.name,t,r.at("actions",o,n,s))]));return[o,{...s,params:n(s.params,"params"),result:n(s.result,"result")}]})):void 0,i=Object.fromEntries(n.flatMap(o=>{let s,n=e.content[o];return n?[[o,{...s=m(n,e.name,t,r.at(o)),type:"object",properties:s.properties??{},required:s.required??[],additionalProperties:!1}]]:[]}));return{...e.content,...o?{model:o}:{},...s?{expressions:s}:{},...a?{actions:a}:{},...i}};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Branded as e}from"@salsita-ai/common/utils";import{AppMetadata as s,BundleSizeBudgets as a,DataSpec as t,Infra as n}from"../sections/index.js";import{AdminSpec as r}from"./admin-spec/index.js";import{ConfiguratorSpec as o}from"./configurator-spec/index.js";export const ApplicationSpec=(i,l)=>{let{merged:m,migrationFiles:p,adminMigrationFiles:d,transformerFiles:c,phxDefinitions:u,evalExpressionParser:w}=i,f=s(m.appMetadata,l);if(!f)return;let S=t({mergedDataSpec:m.dataSpec,mergedChunks:m.chunks},l);if(!S||l.hasErrors)return;let g=l.startSpan("ConfiguratorSpec","ApplicationSpec"),h=o({rawModel:m.model,rawPresets:m.presets,rawExpressions:m.expressions,rawInvariants:m.invariants,rawRelations:m.relations,rawDefaults:m.defaults,dataSchemas:m.dataSchemas,dataSpec:S,appMetadata:f,rawTheme:m.theme,rawUi:m.ui,rawTransformers:m.transformers,rawAssistant:m.assistant,migrationFiles:p,transformerFiles:c,rawComponents:m.components,rawStates:m.configuratorStates,phxDefinitions:u,evalExpressionParser:w,label:"model"},l);if(g(),!h)return;let M=l.startSpan("AdminSpec","ApplicationSpec"),x=r({rawModel:m.adminModel,rawPresets:m.adminPresets,rawExpressions:m.adminExpressions,rawInvariants:m.adminInvariants,rawRelations:m.adminRelations,rawDefaults:m.adminDefaults,migrationFiles:d,rawComponents:m.adminComponents,rawAdminPages:m.adminPages,rawStates:m.adminStates,dataSpec:S,phxDefinitions:u,evalExpressionParser:w,label:"adminModel",requireMigrationFiles:!0},l);if(M(),!x)return;let
|
|
1
|
+
import{Branded as e}from"@salsita-ai/common/utils";import{AppMetadata as s,BundleSizeBudgets as a,DataSpec as t,Infra as n}from"../sections/index.js";import{AdminSpec as r}from"./admin-spec/index.js";import{ConfiguratorSpec as o}from"./configurator-spec/index.js";export const ApplicationSpec=(i,l)=>{let{merged:m,migrationFiles:p,adminMigrationFiles:d,transformerFiles:c,phxDefinitions:u,evalExpressionParser:w}=i,f=s(m.appMetadata,l);if(!f)return;let S=t({mergedDataSpec:m.dataSpec,mergedChunks:m.chunks},l);if(!S||l.hasErrors)return;let g=l.startSpan("ConfiguratorSpec","ApplicationSpec"),h=o({rawModel:m.model,rawPresets:m.presets,rawExpressions:m.expressions,rawActions:m.actions,rawInvariants:m.invariants,rawRelations:m.relations,rawDefaults:m.defaults,dataSchemas:m.dataSchemas,dataSpec:S,appMetadata:f,rawTheme:m.theme,rawUi:m.ui,rawTransformers:m.transformers,rawAssistant:m.assistant,migrationFiles:p,transformerFiles:c,rawComponents:m.components,rawStates:m.configuratorStates,phxDefinitions:u,evalExpressionParser:w,label:"model"},l);if(g(),!h)return;let M=l.startSpan("AdminSpec","ApplicationSpec"),x=r({rawModel:m.adminModel,rawPresets:m.adminPresets,rawExpressions:m.adminExpressions,rawInvariants:m.adminInvariants,rawRelations:m.adminRelations,rawDefaults:m.adminDefaults,migrationFiles:d,rawComponents:m.adminComponents,rawAdminPages:m.adminPages,rawStates:m.adminStates,dataSpec:S,phxDefinitions:u,evalExpressionParser:w,label:"adminModel",requireMigrationFiles:!0},l);if(M(),!x)return;let A=n(m.infra,l);if(!A)return;let v=a(m.budgets);return l.count("entityTypes",h.latestModel.entityTypes.length),l.count("aliases",h.latestModel.aliases.size),l.count("commonTypes",h.latestModel.commonTypes.size),l.count("shapes",h.latestModel.shapes.size),l.count("components",h.components.length),l.count("modelVersions",h.resolvedVersions.versionedModels.length),l.count("presets",h.presets.presets.length),e({configurator:h,admin:x,appMetadata:f,infra:A,budgets:v,dataSpec:S})};
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { Branded } from '@salsita-ai/common/utils';
|
|
2
2
|
import { type EvalExpressionParser, type ParseContext, type PhoenixDefinitions } from '../../../../core/index.js';
|
|
3
3
|
import type { CategorizedFile } from '../../../categorize/index.js';
|
|
4
|
-
import type { MergedAssistant, MergedComponents, MergedConfiguratorStates, MergedDataSchemas, MergedDefaults, MergedExpressions, MergedInvariants, MergedModel, MergedPresets, MergedRelations, MergedTheme, MergedTransformers, MergedUi } from '../../../merge/index.js';
|
|
4
|
+
import type { MergedActions, MergedAssistant, MergedComponents, MergedConfiguratorStates, MergedDataSchemas, MergedDefaults, MergedExpressions, MergedInvariants, MergedModel, MergedPresets, MergedRelations, MergedTheme, MergedTransformers, MergedUi } from '../../../merge/index.js';
|
|
5
5
|
import { Components } from '../../components/index.js';
|
|
6
6
|
import { Expressions } from '../../expressions/index.js';
|
|
7
7
|
import { Invariants } from '../../invariants/index.js';
|
|
8
8
|
import { ConfigurationSchema, DataSchemas, Defaults, ModelVersion, Presets } from '../../model/index.js';
|
|
9
|
-
import { type AppMetadata, AssistantServerSettings, AssistantSpec, type DataSpec, Theme, Transformers, Ui } from '../../sections/index.js';
|
|
9
|
+
import { Actions, type AppMetadata, AssistantServerSettings, AssistantSpec, type DataSpec, Theme, Transformers, Ui } from '../../sections/index.js';
|
|
10
10
|
import { ResolvedVersions } from '../resolved-versions.js';
|
|
11
11
|
import { ConfiguratorStates } from './states.js';
|
|
12
12
|
export type ConfiguratorSpec = Branded<'ConfiguratorSpec', {
|
|
@@ -17,6 +17,7 @@ export type ConfiguratorSpec = Branded<'ConfiguratorSpec', {
|
|
|
17
17
|
readonly configurationSchema: ConfigurationSchema;
|
|
18
18
|
readonly presets: Presets;
|
|
19
19
|
readonly expressions: Expressions;
|
|
20
|
+
readonly actions: Actions;
|
|
20
21
|
readonly invariants: Invariants;
|
|
21
22
|
readonly dataSchemas: DataSchemas;
|
|
22
23
|
readonly defaults: Defaults;
|
|
@@ -31,6 +32,7 @@ interface ConfiguratorSpecProps {
|
|
|
31
32
|
readonly rawModel: MergedModel;
|
|
32
33
|
readonly rawPresets: MergedPresets;
|
|
33
34
|
readonly rawExpressions: MergedExpressions;
|
|
35
|
+
readonly rawActions: MergedActions;
|
|
34
36
|
readonly rawInvariants: MergedInvariants;
|
|
35
37
|
readonly rawRelations: MergedRelations;
|
|
36
38
|
readonly rawDefaults: MergedDefaults;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Branded as e}from"@salsita-ai/common/utils";import{DiagnosticCode as s,diagnosticMessages as t}from"../../../../errors/index.js";import{Components as
|
|
1
|
+
import{Branded as e}from"@salsita-ai/common/utils";import{DiagnosticCode as s,diagnosticMessages as t}from"../../../../errors/index.js";import{Components as o,UserComponents as r}from"../../components/index.js";import{Expressions as i}from"../../expressions/index.js";import{Invariants as n}from"../../invariants/index.js";import{ConfigurationSchema as a,DataSchemas as m,Defaults as p,ModelVersion as l,Presets as d}from"../../model/index.js";import{Relations as f}from"../../relations/index.js";import{Actions as x,AssistantServerSettings as S,AssistantSpec as v,Theme as c,Transformers as j,Ui as u}from"../../sections/index.js";import{ResolvedVersions as g}from"../resolved-versions.js";import{ConfiguratorStates as C}from"./states.js";export const ConfiguratorSpec=(I,M)=>{let{rawModel:h,rawPresets:y,rawExpressions:E,rawActions:N,rawInvariants:T,rawRelations:L,rawDefaults:G,dataSchemas:O,dataSpec:_,appMetadata:b,rawTheme:w,rawUi:A,rawTransformers:D,rawAssistant:V,migrationFiles:k,transformerFiles:K,rawComponents:q,phxDefinitions:z,evalExpressionParser:B,label:F}=I;if(0===Object.keys(h).length)return void M.at(F).error(s.MISSING_MODEL,t.MISSING_MODEL(F));h.latest||M.at(F).error(s.MISSING_LATEST,t.MISSING_LATEST(F));let H=new Map;for(let[e,s]of Object.entries(h)){let t=l(e,s,z,M.at(F,e));t&&H.set(t.versionKey,t)}if(M.hasErrors)return;let J=g(H,k,M);if(!J)return;let P=J.versionedModels.find(e=>e.isLatest)?.modelVersion;if(!P)return;let Q=J.latestVersion,R=a(P,Q),U=f(L,P,M),W=n({rawInvariants:T,rawExpressions:E,rawRelations:L,rawComponents:q},P,M),X=d(y,P,U,M),Y=r(q,{allNames:P.allNames,resolvedShapes:P.resolvedShapes,parsingContext:M}),Z=p(G,P,M.at(F,"defaults")),$=j(D,K,M),ee=i({rawExpressions:E,inferredExpressions:[...U.expressions,...W.expressions,...Y.expressions]},{latestModel:P,aliases:P.aliases,entityTypes:P.entityTypes,evalExpressionParser:B,parsingContext:M}),es=o({userComponents:Y.components,generatedComponents:U.components,invariantComponents:W.components},{aliases:P.aliases,parsingContext:M}),et=m({merged:O,dataSpec:_,appMetadata:b,phxDefinitions:z,parsingContext:M}),eo=C(I.rawStates,M.at("states")),er=x(N,{latestModel:P,phxDefinitions:z},M.at("actions"));if(void 0!==Z&&void 0!==ee&&void 0!==er&&void 0!==es&&void 0!==et)return e({latestModel:P,schemaVersion:Q,dataSchemas:et,resolvedVersions:J,components:es,configurationSchema:R,presets:X,expressions:ee,actions:er,invariants:W,defaults:Z,states:eo,theme:c(w),ui:u(A),transformers:$,assistant:v(V,{model:P,states:eo,phxDefinitions:z,expressions:ee,components:es,actions:er},M),assistantServerSettings:S(V)})};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export*from"./validate-schema-refs.js";
|
|
1
|
+
export*from"./schema-ref-resolver.js";export*from"./validate-schema-refs.js";
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type EnhancedJsonSchemaType, type PhoenixDefinitions } from '../../../core/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Resolves a `$ref` to the schema it names, through phoenix definitions and common types.
|
|
4
|
+
* `undefined` for a ref that names nothing known.
|
|
5
|
+
*/
|
|
6
|
+
export type SchemaRefResolver = ($ref: string) => EnhancedJsonSchemaType | undefined;
|
|
7
|
+
/** The name of the common type a `common:` or internal `#/model/{version}/commonTypes/{name}` ref names. */
|
|
8
|
+
export declare const commonTypeRefName: ($ref: string) => string | undefined;
|
|
9
|
+
/** The phoenix definition a ref names: full URL, `phx:`, or `#/definitions/` as used inside the definitions. */
|
|
10
|
+
export declare const phxDefinitionRefName: ($ref: string) => string | undefined;
|
|
11
|
+
/**
|
|
12
|
+
* Resolves refs to phoenix definitions (full URL, `phx:`, or `#/definitions/` as used inside the
|
|
13
|
+
* definitions themselves) and to common types (`common:` or internal path).
|
|
14
|
+
*/
|
|
15
|
+
export declare const createSchemaRefResolver: (commonTypes: ReadonlyMap<string, {
|
|
16
|
+
readonly schema: EnhancedJsonSchemaType;
|
|
17
|
+
}>, phxDefinitions: PhoenixDefinitions) => SchemaRefResolver;
|
|
18
|
+
/**
|
|
19
|
+
* Whether a value of the schema can be `null`: a `null` type, enum value or const, a nullable
|
|
20
|
+
* `anyOf`/`oneOf` member, or a ref to a nullable schema. A ref that cannot be resolved counts as
|
|
21
|
+
* nullable, since nothing proves otherwise; a ref cycle does not.
|
|
22
|
+
*/
|
|
23
|
+
export declare const isNullableSchema: (schema: EnhancedJsonSchemaType, resolveRef: SchemaRefResolver, visitedRefs?: ReadonlySet<string>) => boolean;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{isArray as e}from"@salsita-ai/common/utils";import{COMMON_SHORT_PREFIX as t,DEFINITION_REF_PATTERN as n,INTERNAL_REF_PATTERN as o,extractPhxDefName as l}from"../../../core/index.js";export const commonTypeRefName=e=>e.startsWith(t)?e.slice(t.length):o.exec(e)?.[2];export const phxDefinitionRefName=e=>l(e)??n.exec(e)?.[1];export const createSchemaRefResolver=(e,t)=>n=>{let o=phxDefinitionRefName(n);if(void 0!==o)return t[o]?.schema;let l=commonTypeRefName(n);return void 0===l?void 0:e.get(l)?.schema};export const isNullableSchema=(t,n,o=new Set)=>{if(t.$ref){if(o.has(t.$ref))return!1;let e=n(t.$ref);return void 0===e||isNullableSchema(e,n,new Set([...o,t.$ref]))}let l=[...t.anyOf??[],...t.oneOf??[]];return"null"===t.type||e(t.type)&&t.type.includes("null")||t.enum?.includes(null)===!0||null===t.const||l.some(e=>isNullableSchema(e,n,o))};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Branded } from '@salsita-ai/common/utils';
|
|
2
|
+
import type { ParseContext } from '../../../../core/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Branded action name: camelCase without a prefix (e.g. "movePartBy", "swapCabinets"). An action is
|
|
5
|
+
* a named domain operation, so its name doubles as the key of its implementation and of its
|
|
6
|
+
* generated types.
|
|
7
|
+
*/
|
|
8
|
+
export type ActionName = Branded<'ActionName', string>;
|
|
9
|
+
/** Validates that a name follows the action naming convention (camelCase, no prefix). */
|
|
10
|
+
export declare const ActionName: (name: string, ctx: ParseContext) => ActionName | undefined;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{Branded as o}from"@salsita-ai/common/utils";import{DiagnosticCode as r,diagnosticMessages as t}from"../../../../errors/index.js";let i=/^[a-z][A-Za-z0-9]*$/;export const ActionName=(A,e)=>i.test(A)?o(A):void e.error(r.INVALID_ACTION_NAME,t.INVALID_ACTION_NAME(A));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export*from"./alias-name.js";export*from"./entity-or-alias-name.js";export*from"./entity-type-name.js";export*from"./expression-name.js";export*from"./instance-name.js";export*from"./invariant-name.js";export*from"./relation-name.js";export*from"./shape-property-name.js";export*from"./violation-type-name.js";
|
|
1
|
+
export*from"./action-name.js";export*from"./alias-name.js";export*from"./entity-or-alias-name.js";export*from"./entity-type-name.js";export*from"./expression-name.js";export*from"./instance-name.js";export*from"./invariant-name.js";export*from"./relation-name.js";export*from"./shape-property-name.js";export*from"./violation-type-name.js";
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Branded } from '@salsita-ai/common/utils';
|
|
2
|
+
import { type EnhancedJsonSchemaType, type JsonSchema, type ParseContext, type PhoenixDefinitions } from '../../../core/index.js';
|
|
3
|
+
import type { MergedActions } from '../../merge/index.js';
|
|
4
|
+
import { ActionName, type ModelVersion } from '../model/index.js';
|
|
5
|
+
/** One parameter of an action: its declared schema, and whether a call has to pass it (a nullable param is optional). */
|
|
6
|
+
export interface ActionParam {
|
|
7
|
+
readonly schema: EnhancedJsonSchemaType;
|
|
8
|
+
readonly required: boolean;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* One validated action declaration. `params` and `result` keep the enhanced schemas for codegen and
|
|
12
|
+
* for consumers that expose the action; `paramsSchema` is the AJV-ready object schema of the parameters, with the
|
|
13
|
+
* refs resolved into `$defs`, which the action system validates the arguments of a call against.
|
|
14
|
+
*/
|
|
15
|
+
export type Action = Branded<'Action', {
|
|
16
|
+
readonly name: ActionName;
|
|
17
|
+
readonly description?: string;
|
|
18
|
+
readonly params: Readonly<Record<string, ActionParam>>;
|
|
19
|
+
readonly result: Readonly<Record<string, EnhancedJsonSchemaType>>;
|
|
20
|
+
readonly paramsSchema: JsonSchema;
|
|
21
|
+
}>;
|
|
22
|
+
/** The validated `actions` section: every declared action by name, in declaration order; empty when the spec declares none. */
|
|
23
|
+
export type Actions = Branded<'Actions', ReadonlyMap<ActionName, Action>>;
|
|
24
|
+
interface ActionsContext {
|
|
25
|
+
readonly latestModel: ModelVersion;
|
|
26
|
+
readonly phxDefinitions: PhoenixDefinitions;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Validates the merged `actions` block against the latest model: action names follow the naming
|
|
30
|
+
* rule, every `$ref` and `references` of a param or result member resolves, and each action gets
|
|
31
|
+
* the runtime schema of its parameters. Returns `undefined` after reporting when any action is
|
|
32
|
+
* invalid, so nothing downstream builds on a partial list.
|
|
33
|
+
*/
|
|
34
|
+
export declare const Actions: (merged: MergedActions, context: ActionsContext, ctx: ParseContext) => Actions | undefined;
|
|
35
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{Branded as e}from"@salsita-ai/common/utils";import{buildPhxDefSchemas as t,collectSchemaRefs as r,toRuntimeSchema as o}from"../../../core/index.js";import{DiagnosticCode as s,diagnosticMessages as i}from"../../../errors/index.js";import{createSchemaRefResolver as a,isNullableSchema as m,validateSchemaRefs as n}from"../common/index.js";import{ActionName as p}from"../model/index.js";let l=(e,{latestModel:t,phxDefinitions:o},a,m)=>{let p=new Set(t.commonTypes.keys());for(let[l,c]of Object.entries(e)){let{refs:e,references:d}=r(c),f=a.at(l);for(let r of(n(e,t.versionKey,p,o,f),d))[...t.allNames].some(e=>e===r.value)||f.at(...r.path).error(s.ACTION_UNKNOWN_REFERENCE_TARGET,i.ACTION_UNKNOWN_REFERENCE_TARGET(m,l,r.value))}};export const Actions=(r,s,i)=>{let{latestModel:n,phxDefinitions:c}=s,d=i.errors.length,f=a(n.commonTypes,c),u=new Map([...Object.entries(t(c)),...[...n.commonTypes].map(([e,t])=>[e,t.schema])]),j=new Map;for(let[t,a]of Object.entries(r)){let r=i.at(t),n=p(t,r);if(l(a.params,s,r.at("params"),`actions.${t}.params`),l(a.result,s,r.at("result"),`actions.${t}.result`),!n)continue;let c=Object.fromEntries(Object.entries(a.params).map(([e,t])=>[e,{schema:t,required:!m(t,f)}])),d=o({type:"object",properties:a.params,required:Object.entries(c).flatMap(([e,{required:t}])=>t?[e]:[]),additionalProperties:!1},u);j.set(n,e({name:n,...void 0===a.description?{}:{description:a.description},params:c,result:a.result,paramsSchema:d}))}return i.errors.length>d?void 0:e(j)};
|
|
@@ -1,17 +1,11 @@
|
|
|
1
1
|
import { type GraphQLOutputType, GraphQLScalarType } from 'graphql';
|
|
2
|
-
import { type EnhancedJsonSchemaType
|
|
3
|
-
import type
|
|
2
|
+
import { type EnhancedJsonSchemaType } from '../../../../core/index.js';
|
|
3
|
+
import { type SchemaRefResolver } from '../../common/index.js';
|
|
4
4
|
/**
|
|
5
5
|
* Opaque scalar for values the assistant schema does not type: objects, custom TypeScript types and
|
|
6
6
|
* loose unions. A value is plain serializable data and passes through unchanged.
|
|
7
7
|
*/
|
|
8
8
|
export declare const GraphQLJSON: GraphQLScalarType<unknown, unknown>;
|
|
9
|
-
/**
|
|
10
|
-
* Resolves a `$ref` to the schema it names: nullability is read through phoenix definitions and
|
|
11
|
-
* common types, and a common type also gives the field its type and default description.
|
|
12
|
-
* `undefined` for a ref that names nothing known.
|
|
13
|
-
*/
|
|
14
|
-
export type AssistantRefResolver = ($ref: string) => EnhancedJsonSchemaType | undefined;
|
|
15
9
|
/**
|
|
16
10
|
* The GraphQL type of one whitelisted stored field or declared expression. `enumValues` lists the
|
|
17
11
|
* allowed values of a string enum, which the schema exposes as `String` and names in the field
|
|
@@ -28,11 +22,6 @@ export interface AssistantFieldType {
|
|
|
28
22
|
/** The value is localizable, or a list of localizable values, and the schema exposes it as `String`. */
|
|
29
23
|
readonly localized?: true;
|
|
30
24
|
}
|
|
31
|
-
/**
|
|
32
|
-
* Resolves refs to phoenix definitions (full URL, `phx:`, or `#/definitions/` as used inside the
|
|
33
|
-
* definitions themselves) and to common types (`common:` or internal path).
|
|
34
|
-
*/
|
|
35
|
-
export declare const createAssistantRefResolver: (commonTypes: CommonTypes, phxDefinitions: PhoenixDefinitions) => AssistantRefResolver;
|
|
36
25
|
/**
|
|
37
26
|
* Maps the JSON Schema of a whitelisted stored field or declared expression to its GraphQL type,
|
|
38
27
|
* following the resolution order of `schemaToTypeString`: refs to localizable phoenix definitions →
|
|
@@ -41,4 +30,4 @@ export declare const createAssistantRefResolver: (commonTypes: CommonTypes, phxD
|
|
|
41
30
|
* `String` with their values, primitives → scalars, arrays of mappable items → lists, and everything
|
|
42
31
|
* else → `JSON`. Every type, `JSON` included, is non-null unless the schema admits `null`.
|
|
43
32
|
*/
|
|
44
|
-
export declare const assistantFieldType: (schema: EnhancedJsonSchemaType, resolveRef:
|
|
33
|
+
export declare const assistantFieldType: (schema: EnhancedJsonSchemaType, resolveRef: SchemaRefResolver) => AssistantFieldType;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{GraphQLBoolean as e,GraphQLFloat as t,GraphQLID as r,GraphQLInt as n,GraphQLList as i,GraphQLNonNull as l,GraphQLScalarType as
|
|
1
|
+
import{GraphQLBoolean as e,GraphQLFloat as t,GraphQLID as r,GraphQLInt as n,GraphQLList as i,GraphQLNonNull as l,GraphQLScalarType as o,GraphQLString as a,getNamedType as p}from"graphql";import{isArray as s}from"@salsita-ai/common/utils";import{extractPhxDefName as f}from"../../../../core/index.js";import{commonTypeRefName as u,isNullableSchema as d,phxDefinitionRefName as y}from"../../common/index.js";export const GraphQLJSON=new o({name:"JSON",description:"Any JSON value, returned as stored. Always plain serializable data."});let m={number:t,integer:n,string:a,boolean:e},c=new Set(["Localizable","EnhancedLocalizable","MessageDescriptor","EnhancedMessageDescriptor","MultilingualString"]),v={type:GraphQLJSON},g=({anyOf:e,oneOf:t})=>[...e??[],...t??[]].filter(e=>"null"!==e.type),h=(e,t,n)=>{let l;if(void 0!==(l=void 0===e.$ref?void 0:y(e.$ref))&&c.has(l))return{type:a,localized:!0};if(e.tsType)return v;if(e.$ref){var o=e.$ref;if("DomainEntityId"===f(o))return{type:r};let i=u(o),l=void 0===i||n.has(i)?void 0:t(o);return void 0!==i&&l?h(l,t,new Set([...n,i])):v}if(e.anyOf||e.oneOf)return((e,t,r)=>{let n=g(e).map(e=>h(e,t,r)),[i]=n;if(1===n.length&&i)return i;let l=n.flatMap(({type:e,enumValues:t})=>e===a&&t?[t]:[]);if(n.length<2||l.length!==n.length||e.anyOf&&e.oneOf)return v;let o=l.flatMap(e=>[...new Set(e)]);return{type:a,enumValues:e.oneOf?o.filter(e=>o.indexOf(e)===o.lastIndexOf(e)):[...new Set(o)]}})(e,t,n);if(e.enum){let t;return(t=e.enum.filter(e=>null!==e)).every(e=>"string"==typeof e)?{type:a,enumValues:t}:v}if(s(e.type)){let r=e.type.filter(e=>"null"!==e),[i]=r;return 1===r.length&&i?h({...e,type:i},t,n):v}if("array"===e.type){var d=e.items;if(!d||s(d))return v;let r=S(d,t,n);return p(r.type)===GraphQLJSON?v:{type:new i(r.type),enumValues:r.enumValues,localized:r.localized}}let O="string"==typeof e.type?m[e.type]:void 0;return O?{type:O}:v},S=(e,t,r)=>{let n=h(e,t,r);return{...n,type:d(e,t)?n.type:new l(n.type)}},O=e=>{let t=g(e);return e.$ref??(1===t.length?t[0]?.$ref:void 0)},w=(e,t,r)=>{let n=u(e),i=void 0===n||r.has(n)?void 0:t(e);if(void 0===n||!i)return;let l=O(i);return void 0===i.description&&l?w(l,t,new Set([...r,n])):i.description};export const assistantFieldType=(e,t)=>{let r=O(e),n=void 0===e.description&&r?w(r,t,new Set):e.description;return{...S(e,t,new Set),...void 0===n?{}:{description:n}}};
|