@jay-framework/compiler-shared 0.12.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -87,9 +87,11 @@ declare class Imports {
87
87
  declare const JAY_EXTENSION = ".jay-html";
88
88
  declare const CSS_EXTENSION = ".css";
89
89
  declare const JAY_CONTRACT_EXTENSION = ".jay-contract";
90
+ declare const JAY_ACTION_EXTENSION = ".jay-action";
90
91
  declare const JAY_TS_EXTENSION = ".jay-html.ts";
91
92
  declare const JAY_DTS_EXTENSION = ".jay-html.d.ts";
92
93
  declare const JAY_CONTRACT_DTS_EXTENSION = ".jay-contract.d.ts";
94
+ declare const JAY_ACTION_DTS_EXTENSION = ".jay-action.d.ts";
93
95
  declare const JAY_COMPONENT = "@jay-framework/component";
94
96
  declare const JAY_SECURE = "@jay-framework/secure";
95
97
  declare const JAY_RUNTIME = "@jay-framework/runtime";
@@ -114,7 +116,8 @@ declare enum JayTypeKind {
114
116
  array = 9,
115
117
  union = 10,
116
118
  promise = 11,
117
- recursive = 12
119
+ recursive = 12,
120
+ optional = 13
118
121
  }
119
122
  interface JayType {
120
123
  name: string;
@@ -212,7 +215,14 @@ declare class JayRecursiveType implements JayType {
212
215
  readonly kind = JayTypeKind.recursive;
213
216
  get name(): string;
214
217
  }
218
+ declare class JayOptionalType implements JayType {
219
+ readonly innerType: JayType;
220
+ constructor(innerType: JayType);
221
+ readonly kind = JayTypeKind.optional;
222
+ get name(): string;
223
+ }
215
224
  declare const JayErrorType: JayObjectType;
225
+ declare function isOptionalType(aType: JayType): aType is JayOptionalType;
216
226
  declare function isAtomicType(aType: JayType): aType is JayAtomicType;
217
227
  declare function isTypeAliasType(aType: JayType): aType is JayTypeAlias;
218
228
  declare function isEnumType(aType: JayType): aType is JayEnumType;
@@ -230,6 +240,29 @@ declare function isCurrencyType(aType: JayType): aType is JayAtomicType;
230
240
  declare function isDateWithTimezoneType(aType: JayType): aType is JayAtomicType;
231
241
  declare function equalJayTypes(a: JayType, b: JayType): any;
232
242
 
243
+ /**
244
+ * Converts JayType trees to JSON Schema.
245
+ *
246
+ * Used by the runtime to convert parsed .jay-action files into JSON Schema
247
+ * for AI agent tool definitions (e.g., Gemini function declarations).
248
+ */
249
+
250
+ /**
251
+ * JSON Schema property definition.
252
+ */
253
+ interface JsonSchemaProperty {
254
+ type: string;
255
+ description?: string;
256
+ enum?: string[];
257
+ items?: JsonSchemaProperty;
258
+ properties?: Record<string, JsonSchemaProperty>;
259
+ required?: string[];
260
+ }
261
+ /**
262
+ * Converts a JayType to a JSON Schema property.
263
+ */
264
+ declare function jayTypeToJsonSchema(type: JayType): JsonSchemaProperty | null;
265
+
233
266
  interface JayImportName {
234
267
  name: string;
235
268
  as?: string;
@@ -477,6 +510,7 @@ declare function prettify(code: string, options?: prettier.Options): Promise<str
477
510
  declare function prettifyHtml(html: string): string;
478
511
  declare function removeComments(code: string): string;
479
512
 
513
+ declare const LOCAL_PLUGIN_PATH = "src/plugins";
480
514
  /**
481
515
  * Plugin initialization configuration.
482
516
  *
@@ -510,6 +544,9 @@ interface PluginManifest {
510
544
  name: string;
511
545
  version?: string;
512
546
  module?: string;
547
+ /** When true, this plugin is loaded on every page regardless of usage in jay-html.
548
+ * Useful for global tools like WebMCP, analytics, or dev tools. */
549
+ global?: boolean;
513
550
  contracts?: Array<{
514
551
  name: string;
515
552
  contract: string;
@@ -517,8 +554,10 @@ interface PluginManifest {
517
554
  description?: string;
518
555
  }>;
519
556
  dynamic_contracts?: DynamicContractConfig | DynamicContractConfig[];
520
- /** Named exports from plugin backend bundle that are JayAction instances */
521
- actions?: string[];
557
+ /** Named exports from plugin backend bundle that are JayAction instances.
558
+ * Can be a string (export name, no metadata) or an object with a .jay-action file reference.
559
+ * Actions with .jay-action metadata are exposed to AI agents; those without are not. */
560
+ actions?: ActionManifestEntry[];
522
561
  /** Plugin initialization configuration */
523
562
  init?: PluginInitConfig;
524
563
  /** Plugin setup configuration (Design Log #87) */
@@ -531,6 +570,23 @@ interface PluginManifest {
531
570
  description?: string;
532
571
  };
533
572
  }
573
+ /**
574
+ * Action entry in plugin.yaml.
575
+ * - `string`: export name only, no metadata (not exposed to AI agents)
576
+ * - `{ name, action }`: export name + path to .jay-action metadata file
577
+ */
578
+ type ActionManifestEntry = string | {
579
+ name: string;
580
+ action: string;
581
+ };
582
+ /**
583
+ * Normalizes an action manifest entry to { name, action? }.
584
+ * Strings become { name: string, action: undefined }.
585
+ */
586
+ declare function normalizeActionEntry(entry: ActionManifestEntry): {
587
+ name: string;
588
+ action?: string;
589
+ };
534
590
  /**
535
591
  * Result of resolving a plugin component
536
592
  */
@@ -554,31 +610,30 @@ interface PluginComponentResolution {
554
610
  */
555
611
  declare function loadPluginManifest(pluginDir: string): PluginManifest | null;
556
612
  /**
557
- * Resolves a plugin component from a local plugin directory (src/plugins/)
613
+ * Finds a dynamic contract config that matches the given contract name.
614
+ * Dynamic contracts use a prefix format: "prefix/name" (e.g., "list/recipes-list")
558
615
  *
559
- * @param projectRoot - Project root directory
560
- * @param pluginName - Name of the plugin
561
- * @param contractName - Name of the contract to resolve
562
- * @returns Resolution result with validation messages
616
+ * @param manifest - The plugin manifest
617
+ * @param contractName - The contract name to match (e.g., "list/recipes-list")
618
+ * @returns The matching DynamicContractConfig or null if not found
563
619
  */
564
- declare function resolveLocalPlugin(projectRoot: string, pluginName: string, contractName: string): WithValidations<PluginComponentResolution> | null;
620
+ declare function findDynamicContract(manifest: PluginManifest, contractName: string): DynamicContractConfig | null;
565
621
  /**
566
- * Resolves a plugin component from an NPM package (node_modules/)
622
+ * Resolves a plugin component, trying local plugins first, then NPM packages
567
623
  *
568
624
  * @param projectRoot - Project root directory
569
- * @param pluginName - Name of the NPM package
625
+ * @param pluginName - Name of the plugin
570
626
  * @param contractName - Name of the contract to resolve
571
627
  * @returns Resolution result with validation messages
572
628
  */
573
- declare function resolveNpmPlugin(projectRoot: string, pluginName: string, contractName: string): WithValidations<PluginComponentResolution> | null;
629
+ declare function resolvePluginComponent(projectRoot: string, pluginName: string, contractName: string): WithValidations<PluginComponentResolution>;
574
630
  /**
575
- * Resolves a plugin component, trying local plugins first, then NPM packages
631
+ * Resolves a plugin manifest from a local plugin or NPM package
576
632
  *
577
633
  * @param projectRoot - Project root directory
578
634
  * @param pluginName - Name of the plugin
579
- * @param contractName - Name of the contract to resolve
580
635
  * @returns Resolution result with validation messages
581
636
  */
582
- declare function resolvePluginComponent(projectRoot: string, pluginName: string, contractName: string): WithValidations<PluginComponentResolution>;
637
+ declare function resolvePluginManifest(projectRoot: string, pluginName: string): WithValidations<PluginManifest>;
583
638
 
584
- export { CSS_EXTENSION, type CompilerSourceFile, type DynamicContractConfig, GenerateTarget, type GenericTypescriptSourceFile, Import, type ImportName, type ImportedRefsTree, Imports, ImportsFor, JAY_4_REACT, JAY_COMPONENT, JAY_CONTRACT_DTS_EXTENSION, JAY_CONTRACT_EXTENSION, JAY_DTS_EXTENSION, JAY_EXTENSION, JAY_FULLSTACK_COMPONENTS, JAY_QUERY_CLIENT, JAY_QUERY_MAIN_SANDBOX, JAY_QUERY_MAIN_SANDBOX_TS, JAY_QUERY_PREFIX, JAY_QUERY_SERVER, JAY_QUERY_WORKER_SANDBOX, JAY_QUERY_WORKER_SANDBOX_TS, JAY_QUERY_WORKER_TRUSTED, JAY_QUERY_WORKER_TRUSTED_TS, JAY_RUNTIME, JAY_SECURE, JAY_STACK_CLIENT_RUNTIME, JAY_TS_EXTENSION, JayArrayType, JayAtomicType, JayBoolean, JayBuildEnvironment, JayComponentApiMember, JayComponentType, JayDate, JayElementConstructorType, JayElementType, JayEnumType, type JayEnvironment, JayErrorType, JayHTMLType, type JayImportLink, type JayImportName, JayImportedType, JayNumber, JayObjectType, JayPromiseType, JayRecursiveType, JayString, type JayType, JayTypeAlias, JayTypeKind, JayUnionType, JayUnknown, type JayValidations, MAKE_JAY_4_REACT_COMPONENT, MAKE_JAY_COMPONENT, MAKE_JAY_TSX_COMPONENT, type MainRuntimeModes, type ParsedJayModuleSpecifier, type PluginComponentResolution, type PluginInitConfig, type PluginManifest, REACT, type RecursiveRegion, type Ref, type RefsTree, RenderFragment, RuntimeMode, SourceFileFormat, TSX_EXTENSION, TS_EXTENSION, WithValidations, addBuildEnvironment, checkValidationErrors, equalJayTypes, getBasePath, getBuildEnvironment, getJayTsFileSourcePath, getMode, getModeFileExtension, getModeFromExtension, hasBuildEnvironment, hasExtension, hasJayExtension, hasJayModeExtension, hasRefs, isArrayType, isAtomicType, isComponentType, isCurrencyType, isDateWithTimezoneType, isElementConstructorType, isElementType, isEnumType, isHTMLType, isImportedType, isLocalModule, isObjectType, isPromiseType, isRecursiveType, isTypeAliasType, isUnionType, loadPluginManifest, mergeRefsTrees, mkRef, mkRefsTree, nestRefs, parseJayModuleSpecifier, prettify, prettifyHtml, removeComments, resolveLocalPlugin, resolveNpmPlugin, resolvePluginComponent, resolvePrimitiveType, withOriginalTrace, withoutExtension };
639
+ export { type ActionManifestEntry, CSS_EXTENSION, type CompilerSourceFile, type DynamicContractConfig, GenerateTarget, type GenericTypescriptSourceFile, Import, type ImportName, type ImportedRefsTree, Imports, ImportsFor, JAY_4_REACT, JAY_ACTION_DTS_EXTENSION, JAY_ACTION_EXTENSION, JAY_COMPONENT, JAY_CONTRACT_DTS_EXTENSION, JAY_CONTRACT_EXTENSION, JAY_DTS_EXTENSION, JAY_EXTENSION, JAY_FULLSTACK_COMPONENTS, JAY_QUERY_CLIENT, JAY_QUERY_MAIN_SANDBOX, JAY_QUERY_MAIN_SANDBOX_TS, JAY_QUERY_PREFIX, JAY_QUERY_SERVER, JAY_QUERY_WORKER_SANDBOX, JAY_QUERY_WORKER_SANDBOX_TS, JAY_QUERY_WORKER_TRUSTED, JAY_QUERY_WORKER_TRUSTED_TS, JAY_RUNTIME, JAY_SECURE, JAY_STACK_CLIENT_RUNTIME, JAY_TS_EXTENSION, JayArrayType, JayAtomicType, JayBoolean, JayBuildEnvironment, JayComponentApiMember, JayComponentType, JayDate, JayElementConstructorType, JayElementType, JayEnumType, type JayEnvironment, JayErrorType, JayHTMLType, type JayImportLink, type JayImportName, JayImportedType, JayNumber, JayObjectType, JayOptionalType, JayPromiseType, JayRecursiveType, JayString, type JayType, JayTypeAlias, JayTypeKind, JayUnionType, JayUnknown, type JayValidations, type JsonSchemaProperty, LOCAL_PLUGIN_PATH, MAKE_JAY_4_REACT_COMPONENT, MAKE_JAY_COMPONENT, MAKE_JAY_TSX_COMPONENT, type MainRuntimeModes, type ParsedJayModuleSpecifier, type PluginComponentResolution, type PluginInitConfig, type PluginManifest, REACT, type RecursiveRegion, type Ref, type RefsTree, RenderFragment, RuntimeMode, SourceFileFormat, TSX_EXTENSION, TS_EXTENSION, WithValidations, addBuildEnvironment, checkValidationErrors, equalJayTypes, findDynamicContract, getBasePath, getBuildEnvironment, getJayTsFileSourcePath, getMode, getModeFileExtension, getModeFromExtension, hasBuildEnvironment, hasExtension, hasJayExtension, hasJayModeExtension, hasRefs, isArrayType, isAtomicType, isComponentType, isCurrencyType, isDateWithTimezoneType, isElementConstructorType, isElementType, isEnumType, isHTMLType, isImportedType, isLocalModule, isObjectType, isOptionalType, isPromiseType, isRecursiveType, isTypeAliasType, isUnionType, jayTypeToJsonSchema, loadPluginManifest, mergeRefsTrees, mkRef, mkRefsTree, nestRefs, normalizeActionEntry, parseJayModuleSpecifier, prettify, prettifyHtml, removeComments, resolvePluginComponent, resolvePluginManifest, resolvePrimitiveType, withOriginalTrace, withoutExtension };
package/dist/index.js CHANGED
@@ -13,9 +13,11 @@ import { createRequire } from "module";
13
13
  const JAY_EXTENSION = ".jay-html";
14
14
  const CSS_EXTENSION = ".css";
15
15
  const JAY_CONTRACT_EXTENSION = ".jay-contract";
16
+ const JAY_ACTION_EXTENSION = ".jay-action";
16
17
  const JAY_TS_EXTENSION = ".jay-html.ts";
17
18
  const JAY_DTS_EXTENSION = ".jay-html.d.ts";
18
19
  const JAY_CONTRACT_DTS_EXTENSION = ".jay-contract.d.ts";
20
+ const JAY_ACTION_DTS_EXTENSION = ".jay-action.d.ts";
19
21
  const JAY_COMPONENT = "@jay-framework/component";
20
22
  const JAY_SECURE = "@jay-framework/secure";
21
23
  const JAY_RUNTIME = "@jay-framework/runtime";
@@ -493,6 +495,7 @@ var JayTypeKind = /* @__PURE__ */ ((JayTypeKind2) => {
493
495
  JayTypeKind2[JayTypeKind2["union"] = 10] = "union";
494
496
  JayTypeKind2[JayTypeKind2["promise"] = 11] = "promise";
495
497
  JayTypeKind2[JayTypeKind2["recursive"] = 12] = "recursive";
498
+ JayTypeKind2[JayTypeKind2["optional"] = 13] = "optional";
496
499
  return JayTypeKind2;
497
500
  })(JayTypeKind || {});
498
501
  class JayAtomicType {
@@ -615,11 +618,23 @@ class JayRecursiveType {
615
618
  return this.resolvedType?.name || `Recursive<${this.referencePath}>`;
616
619
  }
617
620
  }
621
+ class JayOptionalType {
622
+ constructor(innerType) {
623
+ __publicField(this, "kind", 13);
624
+ this.innerType = innerType;
625
+ }
626
+ get name() {
627
+ return `${this.innerType.name}?`;
628
+ }
629
+ }
618
630
  const JayErrorType = new JayObjectType("Error", {
619
631
  message: new JayAtomicType("string"),
620
632
  name: new JayAtomicType("string"),
621
633
  stack: new JayAtomicType("string")
622
634
  });
635
+ function isOptionalType(aType) {
636
+ return aType.kind === 13;
637
+ }
623
638
  function isAtomicType(aType) {
624
639
  return aType.kind === 0;
625
640
  }
@@ -705,6 +720,51 @@ function equalJayTypes(a, b) {
705
720
  } else
706
721
  ;
707
722
  }
723
+ function jayTypeToJsonSchema(type) {
724
+ if (isOptionalType(type)) {
725
+ return jayTypeToJsonSchema(type.innerType);
726
+ }
727
+ if (isAtomicType(type)) {
728
+ const name = type.name.toLowerCase();
729
+ if (name === "string" || name === "number" || name === "boolean") {
730
+ return { type: name };
731
+ }
732
+ return { type: "string" };
733
+ }
734
+ if (isEnumType(type)) {
735
+ return { type: "string", enum: type.values };
736
+ }
737
+ if (isImportedType(type)) {
738
+ return { type: "object", description: `Contract: ${type.name}` };
739
+ }
740
+ if (isArrayType(type)) {
741
+ const itemSchema = jayTypeToJsonSchema(type.itemType);
742
+ if (itemSchema) {
743
+ return { type: "array", items: itemSchema };
744
+ }
745
+ return { type: "array" };
746
+ }
747
+ if (isObjectType(type)) {
748
+ const properties = {};
749
+ const required = [];
750
+ for (const [key, propType] of Object.entries(type.props)) {
751
+ const isOpt = isOptionalType(propType);
752
+ const schema = jayTypeToJsonSchema(propType);
753
+ if (schema) {
754
+ properties[key] = schema;
755
+ if (!isOpt) {
756
+ required.push(key);
757
+ }
758
+ }
759
+ }
760
+ return {
761
+ type: "object",
762
+ properties,
763
+ ...required.length > 0 && { required }
764
+ };
765
+ }
766
+ return null;
767
+ }
708
768
  var RuntimeMode = /* @__PURE__ */ ((RuntimeMode2) => {
709
769
  RuntimeMode2["MainTrusted"] = "mainTrusted";
710
770
  RuntimeMode2["MainSandbox"] = "mainSandbox";
@@ -907,13 +967,13 @@ class WithValidations {
907
967
  this.validations = validations;
908
968
  }
909
969
  map(func) {
910
- if (this.val)
970
+ if (this.val !== void 0)
911
971
  return new WithValidations(func(this.val), this.validations);
912
972
  else
913
973
  return new WithValidations(void 0, this.validations);
914
974
  }
915
975
  async mapAsync(func) {
916
- if (this.val) {
976
+ if (this.val !== void 0) {
917
977
  const result = await func(this.val);
918
978
  return new WithValidations(result, this.validations);
919
979
  } else {
@@ -921,14 +981,14 @@ class WithValidations {
921
981
  }
922
982
  }
923
983
  flatMap(func) {
924
- if (this.val) {
984
+ if (this.val !== void 0) {
925
985
  let that = func(this.val);
926
986
  return new WithValidations(that.val, [...this.validations, ...that.validations]);
927
987
  } else
928
988
  return new WithValidations(void 0, this.validations);
929
989
  }
930
990
  async flatMapAsync(func) {
931
- if (this.val) {
991
+ if (this.val !== void 0) {
932
992
  const result = await func(this.val);
933
993
  return new WithValidations(result.val, [...this.validations, ...result.validations]);
934
994
  } else {
@@ -1125,6 +1185,13 @@ function removeComments(code) {
1125
1185
  ).join("\n");
1126
1186
  }
1127
1187
  const require2 = createRequire(import.meta.url);
1188
+ const LOCAL_PLUGIN_PATH = "src/plugins";
1189
+ function normalizeActionEntry(entry) {
1190
+ if (typeof entry === "string") {
1191
+ return { name: entry };
1192
+ }
1193
+ return { name: entry.name, action: entry.action };
1194
+ }
1128
1195
  function loadPluginManifest(pluginDir) {
1129
1196
  const pluginYamlPath = path.join(pluginDir, "plugin.yaml");
1130
1197
  if (!fs.existsSync(pluginYamlPath)) {
@@ -1149,8 +1216,8 @@ function findDynamicContract(manifest, contractName) {
1149
1216
  const dynamicConfigs = Array.isArray(manifest.dynamic_contracts) ? manifest.dynamic_contracts : [manifest.dynamic_contracts];
1150
1217
  return dynamicConfigs.find((config) => config.prefix === prefix) || null;
1151
1218
  }
1152
- function resolveLocalPlugin(projectRoot, pluginName, contractName) {
1153
- const localPluginPath = path.join(projectRoot, "src/plugins", pluginName);
1219
+ function resolveLocalPluginManifest(projectRoot, pluginName) {
1220
+ const localPluginPath = path.join(projectRoot, LOCAL_PLUGIN_PATH, pluginName);
1154
1221
  const pluginYamlPath = path.join(localPluginPath, "plugin.yaml");
1155
1222
  if (!fs.existsSync(localPluginPath)) {
1156
1223
  return null;
@@ -1166,7 +1233,23 @@ function resolveLocalPlugin(projectRoot, pluginName, contractName) {
1166
1233
  `Failed to parse plugin.yaml for local plugin "${pluginName}" at ${pluginYamlPath}`
1167
1234
  ]);
1168
1235
  }
1236
+ if (!manifest.contracts && !manifest.dynamic_contracts) {
1237
+ return new WithValidations(null, [
1238
+ `Local plugin "${pluginName}" has no contracts or dynamic_contracts defined in plugin.yaml`
1239
+ ]);
1240
+ }
1241
+ return new WithValidations(manifest, []);
1242
+ }
1243
+ function resolveLocalPlugin(projectRoot, pluginName, contractName) {
1244
+ const manifestWithValidations = resolveLocalPluginManifest(projectRoot, pluginName);
1245
+ if (!manifestWithValidations) {
1246
+ return null;
1247
+ }
1248
+ if (!manifestWithValidations.val || manifestWithValidations.validations.length > 0)
1249
+ return new WithValidations(null, manifestWithValidations.validations);
1250
+ const manifest = manifestWithValidations.val;
1169
1251
  const componentModule = manifest.module || "index.js";
1252
+ const localPluginPath = path.join(projectRoot, LOCAL_PLUGIN_PATH, pluginName);
1170
1253
  const componentPath = path.join(localPluginPath, componentModule);
1171
1254
  if (manifest.contracts && manifest.contracts.length > 0) {
1172
1255
  const contract = manifest.contracts.find((c2) => c2.name === contractName);
@@ -1195,11 +1278,6 @@ function resolveLocalPlugin(projectRoot, pluginName, contractName) {
1195
1278
  []
1196
1279
  );
1197
1280
  }
1198
- if (!manifest.contracts && !manifest.dynamic_contracts) {
1199
- return new WithValidations(null, [
1200
- `Local plugin "${pluginName}" has no contracts or dynamic_contracts defined in plugin.yaml`
1201
- ]);
1202
- }
1203
1281
  const availableContracts = manifest.contracts?.map((c2) => c2.name) || [];
1204
1282
  const dynamicPrefixes = manifest.dynamic_contracts ? (Array.isArray(manifest.dynamic_contracts) ? manifest.dynamic_contracts : [manifest.dynamic_contracts]).map((c2) => `${c2.prefix}/*`) : [];
1205
1283
  const allAvailable = [...availableContracts, ...dynamicPrefixes].join(", ");
@@ -1207,7 +1285,7 @@ function resolveLocalPlugin(projectRoot, pluginName, contractName) {
1207
1285
  `Contract "${contractName}" not found in local plugin "${pluginName}". Available: ${allAvailable}`
1208
1286
  ]);
1209
1287
  }
1210
- function resolveNpmPlugin(projectRoot, pluginName, contractName) {
1288
+ function resolveNpmPluginManifest(projectRoot, pluginName) {
1211
1289
  let pluginYamlPath;
1212
1290
  try {
1213
1291
  pluginYamlPath = require2.resolve(`${pluginName}/plugin.yaml`, {
@@ -1230,6 +1308,25 @@ function resolveNpmPlugin(projectRoot, pluginName, contractName) {
1230
1308
  `Failed to parse plugin.yaml for NPM package "${pluginName}" at ${pluginYamlPath}`
1231
1309
  ]);
1232
1310
  }
1311
+ if (!manifest.contracts && !manifest.dynamic_contracts) {
1312
+ return new WithValidations(null, [
1313
+ `NPM package "${pluginName}" has no contracts or dynamic_contracts defined in plugin.yaml`
1314
+ ]);
1315
+ }
1316
+ return new WithValidations(manifest, []);
1317
+ }
1318
+ function resolveNpmPlugin(projectRoot, pluginName, contractName) {
1319
+ const manifestWithValidations = resolveNpmPluginManifest(projectRoot, pluginName);
1320
+ if (!manifestWithValidations) {
1321
+ return null;
1322
+ }
1323
+ if (!manifestWithValidations.val || manifestWithValidations.validations.length > 0)
1324
+ return new WithValidations(null, manifestWithValidations.validations);
1325
+ const manifest = manifestWithValidations.val;
1326
+ const pluginYamlPath = require2.resolve(`${pluginName}/plugin.yaml`, {
1327
+ paths: [projectRoot]
1328
+ });
1329
+ const npmPluginPath = path.dirname(pluginYamlPath);
1233
1330
  const packageJsonPath = path.join(npmPluginPath, "package.json");
1234
1331
  const getComponentPath = () => {
1235
1332
  if (fs.existsSync(packageJsonPath)) {
@@ -1301,11 +1398,6 @@ function resolveNpmPlugin(projectRoot, pluginName, contractName) {
1301
1398
  []
1302
1399
  );
1303
1400
  }
1304
- if (!manifest.contracts && !manifest.dynamic_contracts) {
1305
- return new WithValidations(null, [
1306
- `NPM package "${pluginName}" has no contracts or dynamic_contracts defined in plugin.yaml`
1307
- ]);
1308
- }
1309
1401
  const availableContracts = manifest.contracts?.map((c2) => c2.name) || [];
1310
1402
  const dynamicPrefixes = manifest.dynamic_contracts ? (Array.isArray(manifest.dynamic_contracts) ? manifest.dynamic_contracts : [manifest.dynamic_contracts]).map((c2) => `${c2.prefix}/*`) : [];
1311
1403
  const allAvailable = [...availableContracts, ...dynamicPrefixes].join(", ");
@@ -1315,13 +1407,46 @@ function resolveNpmPlugin(projectRoot, pluginName, contractName) {
1315
1407
  }
1316
1408
  function resolvePluginComponent(projectRoot, pluginName, contractName) {
1317
1409
  const localResult = resolveLocalPlugin(projectRoot, pluginName, contractName);
1318
- if (localResult !== null) {
1410
+ if (localResult && localResult.val !== null && localResult.validations.length === 0) {
1319
1411
  return localResult;
1320
1412
  }
1321
1413
  const npmResult = resolveNpmPlugin(projectRoot, pluginName, contractName);
1322
- if (npmResult !== null) {
1414
+ if (npmResult && npmResult.val !== null && npmResult.validations.length === 0) {
1323
1415
  return npmResult;
1324
1416
  }
1417
+ if (localResult && localResult.validations.length > 0) {
1418
+ return localResult;
1419
+ }
1420
+ if (npmResult && npmResult.validations.length > 0 && localResult === null) {
1421
+ const npmError = npmResult.validations[0];
1422
+ const isGenericPackageNotFound = npmError.startsWith("NPM package") && npmError.includes("not found") || npmError.startsWith("Plugin") && npmError.includes("not found");
1423
+ if (!isGenericPackageNotFound) {
1424
+ return npmResult;
1425
+ }
1426
+ }
1427
+ return new WithValidations(null, [
1428
+ `Plugin "${pluginName}" not found. Searched in src/plugins/${pluginName}/ and node_modules/${pluginName}/. Ensure the plugin is installed or exists in your project.`
1429
+ ]);
1430
+ }
1431
+ function resolvePluginManifest(projectRoot, pluginName) {
1432
+ const localResult = resolveLocalPluginManifest(projectRoot, pluginName);
1433
+ if (localResult && localResult.val !== null && localResult.validations.length === 0) {
1434
+ return localResult;
1435
+ }
1436
+ const npmResult = resolveNpmPluginManifest(projectRoot, pluginName);
1437
+ if (npmResult && npmResult.val !== null && npmResult.validations.length === 0) {
1438
+ return npmResult;
1439
+ }
1440
+ if (localResult && localResult.validations.length > 0) {
1441
+ return localResult;
1442
+ }
1443
+ if (npmResult && npmResult.validations.length > 0 && localResult === null) {
1444
+ const npmError = npmResult.validations[0];
1445
+ const isGenericPackageNotFound = npmError.startsWith("NPM package") && npmError.includes("not found") || npmError.startsWith("Plugin") && npmError.includes("not found");
1446
+ if (!isGenericPackageNotFound) {
1447
+ return npmResult;
1448
+ }
1449
+ }
1325
1450
  return new WithValidations(null, [
1326
1451
  `Plugin "${pluginName}" not found. Searched in src/plugins/${pluginName}/ and node_modules/${pluginName}/. Ensure the plugin is installed or exists in your project.`
1327
1452
  ]);
@@ -1341,6 +1466,8 @@ export {
1341
1466
  Imports,
1342
1467
  ImportsFor,
1343
1468
  JAY_4_REACT,
1469
+ JAY_ACTION_DTS_EXTENSION,
1470
+ JAY_ACTION_EXTENSION,
1344
1471
  JAY_COMPONENT,
1345
1472
  JAY_CONTRACT_DTS_EXTENSION,
1346
1473
  JAY_CONTRACT_EXTENSION,
@@ -1375,6 +1502,7 @@ export {
1375
1502
  JayImportedType,
1376
1503
  JayNumber,
1377
1504
  JayObjectType,
1505
+ JayOptionalType,
1378
1506
  JayPromiseType,
1379
1507
  JayRecursiveType,
1380
1508
  JayString,
@@ -1382,6 +1510,7 @@ export {
1382
1510
  JayTypeKind,
1383
1511
  JayUnionType,
1384
1512
  JayUnknown,
1513
+ LOCAL_PLUGIN_PATH,
1385
1514
  MAKE_JAY_4_REACT_COMPONENT,
1386
1515
  MAKE_JAY_COMPONENT,
1387
1516
  MAKE_JAY_TSX_COMPONENT,
@@ -1395,6 +1524,7 @@ export {
1395
1524
  addBuildEnvironment,
1396
1525
  checkValidationErrors,
1397
1526
  equalJayTypes,
1527
+ findDynamicContract,
1398
1528
  getBasePath,
1399
1529
  getBuildEnvironment,
1400
1530
  getJayTsFileSourcePath,
@@ -1419,22 +1549,24 @@ export {
1419
1549
  isImportedType,
1420
1550
  isLocalModule,
1421
1551
  isObjectType,
1552
+ isOptionalType,
1422
1553
  isPromiseType,
1423
1554
  isRecursiveType,
1424
1555
  isTypeAliasType,
1425
1556
  isUnionType,
1557
+ jayTypeToJsonSchema,
1426
1558
  loadPluginManifest,
1427
1559
  mergeRefsTrees,
1428
1560
  mkRef,
1429
1561
  mkRefsTree,
1430
1562
  nestRefs,
1563
+ normalizeActionEntry,
1431
1564
  parseJayModuleSpecifier,
1432
1565
  prettify,
1433
1566
  prettifyHtml,
1434
1567
  removeComments,
1435
- resolveLocalPlugin,
1436
- resolveNpmPlugin,
1437
1568
  resolvePluginComponent,
1569
+ resolvePluginManifest,
1438
1570
  resolvePrimitiveType,
1439
1571
  u as ts,
1440
1572
  c as tsBridge,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jay-framework/compiler-shared",
3
- "version": "0.12.0",
3
+ "version": "0.13.0",
4
4
  "type": "module",
5
5
  "description": "",
6
6
  "license": "Apache-2.0",
@@ -25,10 +25,10 @@
25
25
  },
26
26
  "author": "",
27
27
  "dependencies": {
28
- "@jay-framework/component": "^0.12.0",
29
- "@jay-framework/runtime": "^0.12.0",
30
- "@jay-framework/secure": "^0.12.0",
31
- "@jay-framework/typescript-bridge": "^0.7.0",
28
+ "@jay-framework/component": "^0.13.0",
29
+ "@jay-framework/runtime": "^0.13.0",
30
+ "@jay-framework/secure": "^0.13.0",
31
+ "@jay-framework/typescript-bridge": "^0.8.0",
32
32
  "@types/js-yaml": "^4.0.9",
33
33
  "change-case": "^4.1.2",
34
34
  "js-beautify": "^1.14.11",
@@ -41,7 +41,7 @@
41
41
  },
42
42
  "devDependencies": {
43
43
  "@caiogondim/strip-margin": "^1.0.0",
44
- "@jay-framework/dev-environment": "^0.12.0",
44
+ "@jay-framework/dev-environment": "^0.13.0",
45
45
  "@testing-library/jest-dom": "^6.2.0",
46
46
  "@types/js-beautify": "^1",
47
47
  "@types/node": "^20.11.5",