@jay-framework/compiler-shared 0.8.0 → 0.10.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
@@ -73,6 +73,7 @@ declare class Imports {
73
73
  private readonly imports;
74
74
  constructor(imports: Array<boolean>);
75
75
  plus(addImport: ImportName | Imports): Imports;
76
+ minus(removeImport: ImportName | Imports): Imports;
76
77
  has(anImport: ImportName): boolean;
77
78
  render(importsFor: ImportsFor): string;
78
79
  static none(): Imports;
@@ -266,6 +267,114 @@ declare function getModeFromExtension(filename: string): RuntimeMode;
266
267
  declare function getJayTsFileSourcePath(filename: string): string;
267
268
  declare function withoutExtension(filename: string, extension: string): string;
268
269
 
270
+ /**
271
+ * Utilities for handling Jay environment metadata in module specifiers.
272
+ *
273
+ * Jay uses query parameters to pass environment information through the import chain:
274
+ * - `?jay-client` / `?jay-server` - Client/server code splitting
275
+ * - `?jay-mainSandbox` / `?jay-workerTrusted` / `?jay-workerSandbox` - Security sandbox modes
276
+ *
277
+ * These utilities provide a consistent way to parse, add, and detect these parameters
278
+ * while correctly handling file extensions like `.jay-contract` and `.jay-html`.
279
+ */
280
+
281
+ /**
282
+ * Environment types for Jay code splitting
283
+ */
284
+ declare enum JayBuildEnvironment {
285
+ Client = "client",
286
+ Server = "server"
287
+ }
288
+ /**
289
+ * All possible Jay environment query parameter values
290
+ */
291
+ type JayEnvironment = JayBuildEnvironment | RuntimeMode;
292
+ /**
293
+ * Query parameter strings for build environments
294
+ */
295
+ declare const JAY_QUERY_CLIENT = "?jay-client";
296
+ declare const JAY_QUERY_SERVER = "?jay-server";
297
+ /**
298
+ * Parsed module specifier with environment information separated
299
+ */
300
+ interface ParsedJayModuleSpecifier {
301
+ /** The base path without any jay query parameters */
302
+ basePath: string;
303
+ /** The build environment (client/server) if present */
304
+ buildEnvironment?: JayBuildEnvironment;
305
+ /** The runtime mode (sandbox modes) if present */
306
+ runtimeMode?: RuntimeMode;
307
+ /** Any remaining query parameters (not jay-related) */
308
+ otherQueryParams: string;
309
+ /** The full query string for reconstruction */
310
+ fullQueryString: string;
311
+ }
312
+ /**
313
+ * Parse a module specifier to extract the base path and any jay environment information.
314
+ *
315
+ * @example
316
+ * parseJayModuleSpecifier('./component?jay-client')
317
+ * // { basePath: './component', buildEnvironment: 'client', ... }
318
+ *
319
+ * @example
320
+ * parseJayModuleSpecifier('./file.jay-contract?jay-server')
321
+ * // { basePath: './file.jay-contract', buildEnvironment: 'server', ... }
322
+ */
323
+ declare function parseJayModuleSpecifier(specifier: string): ParsedJayModuleSpecifier;
324
+ /**
325
+ * Add a build environment (client/server) to a module specifier.
326
+ * If the specifier already has an environment, it will be replaced.
327
+ *
328
+ * @example
329
+ * addBuildEnvironment('./component', 'client')
330
+ * // './component?jay-client'
331
+ *
332
+ * @example
333
+ * addBuildEnvironment('./file?existing=param', 'server')
334
+ * // './file?jay-server&existing=param'
335
+ */
336
+ declare function addBuildEnvironment(specifier: string, environment: JayBuildEnvironment): string;
337
+ /**
338
+ * Check if a module specifier has a specific extension, ignoring any query parameters.
339
+ * This is the query-param-aware version of the simple `string.endsWith()` check.
340
+ *
341
+ * Handles cases where .ts/.tsx may appear:
342
+ * - After the extension: `file.jay-html.ts`
343
+ * - After query params: `file.jay-html?jay-mainSandbox.ts`
344
+ * - Before query params: `file.jay-contract.ts?jay-client`
345
+ *
346
+ * @example
347
+ * hasJayExtension('./file.jay-contract?jay-client', '.jay-contract')
348
+ * // true
349
+ *
350
+ * @example
351
+ * hasJayExtension('./file.jay-html?jay-mainSandbox.ts', '.jay-html', { withTs: true })
352
+ * // true
353
+ */
354
+ declare function hasJayExtension(specifier: string, extension: string, { withTs }?: {
355
+ withTs?: boolean;
356
+ }): boolean;
357
+ /**
358
+ * Get the base path of a module specifier without any query parameters.
359
+ *
360
+ * @example
361
+ * getBasePath('./component?jay-client')
362
+ * // './component'
363
+ */
364
+ declare function getBasePath(specifier: string): string;
365
+ /**
366
+ * Check if a module specifier has a build environment (client or server).
367
+ */
368
+ declare function hasBuildEnvironment(specifier: string): boolean;
369
+ /**
370
+ * Get the build environment from a module specifier, if present.
371
+ */
372
+ declare function getBuildEnvironment(specifier: string): JayBuildEnvironment | undefined;
373
+ /**
374
+ * Check if a module specifier is a local file (relative path).
375
+ */
376
+ declare function isLocalModule(specifier: string): boolean;
377
+
269
378
  type JayValidations = Array<string>;
270
379
  declare class WithValidations<Value> {
271
380
  val?: Value;
@@ -350,4 +459,92 @@ declare function prettify(code: string, options?: prettier.Options): Promise<str
350
459
  declare function prettifyHtml(html: string): string;
351
460
  declare function removeComments(code: string): string;
352
461
 
353
- export { CSS_EXTENSION, type CompilerSourceFile, 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_MAIN_SANDBOX, JAY_QUERY_MAIN_SANDBOX_TS, JAY_QUERY_PREFIX, JAY_QUERY_WORKER_SANDBOX, JAY_QUERY_WORKER_SANDBOX_TS, JAY_QUERY_WORKER_TRUSTED, JAY_QUERY_WORKER_TRUSTED_TS, JAY_RUNTIME, JAY_SECURE, JAY_TS_EXTENSION, JayArrayType, JayAtomicType, JayBoolean, JayComponentApiMember, JayComponentType, JayDate, JayElementConstructorType, JayElementType, JayEnumType, 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, REACT, type RecursiveRegion, type Ref, type RefsTree, RenderFragment, RuntimeMode, SourceFileFormat, TSX_EXTENSION, TS_EXTENSION, WithValidations, checkValidationErrors, equalJayTypes, getJayTsFileSourcePath, getMode, getModeFileExtension, getModeFromExtension, hasExtension, hasJayModeExtension, hasRefs, isArrayType, isAtomicType, isComponentType, isCurrencyType, isDateWithTimezoneType, isElementConstructorType, isElementType, isEnumType, isHTMLType, isImportedType, isObjectType, isPromiseType, isRecursiveType, isTypeAliasType, isUnionType, mergeRefsTrees, mkRef, mkRefsTree, nestRefs, prettify, prettifyHtml, removeComments, resolvePrimitiveType, withOriginalTrace, withoutExtension };
462
+ /**
463
+ * Plugin initialization configuration.
464
+ *
465
+ * For the `makeJayInit` pattern:
466
+ * - undefined: Auto-discover `lib/init.ts` (for uncompiled/local plugins)
467
+ * - string: Export name for the JayInit constant (for compiled/NPM packages)
468
+ *
469
+ * @example
470
+ * ```yaml
471
+ * # For compiled NPM packages - specify the export name
472
+ * name: my-plugin
473
+ * init: myPluginInit
474
+ * ```
475
+ */
476
+ type PluginInitConfig = string;
477
+ /**
478
+ * Plugin manifest structure from plugin.yaml
479
+ */
480
+ interface PluginManifest {
481
+ name: string;
482
+ version?: string;
483
+ module?: string;
484
+ contracts?: Array<{
485
+ name: string;
486
+ contract: string;
487
+ component: string;
488
+ description?: string;
489
+ }>;
490
+ dynamic_contracts?: {
491
+ generator: string;
492
+ component: string;
493
+ prefix: string;
494
+ };
495
+ /** Named exports from plugin backend bundle that are JayAction instances */
496
+ actions?: string[];
497
+ /** Plugin initialization configuration */
498
+ init?: PluginInitConfig;
499
+ }
500
+ /**
501
+ * Result of resolving a plugin component
502
+ */
503
+ interface PluginComponentResolution {
504
+ /** Absolute path to the contract file */
505
+ contractPath: string;
506
+ /** Absolute path to the component file (without extension) - used for local plugins */
507
+ componentPath: string;
508
+ /** Component name to import */
509
+ componentName: string;
510
+ /** Whether this is an NPM package (vs local plugin) */
511
+ isNpmPackage: boolean;
512
+ /** For NPM packages: the package name to import from */
513
+ packageName?: string;
514
+ }
515
+ /**
516
+ * Loads and parses a plugin.yaml file
517
+ *
518
+ * @param pluginDir - Absolute path to plugin directory
519
+ * @returns Parsed plugin manifest or null if not found/invalid
520
+ */
521
+ declare function loadPluginManifest(pluginDir: string): PluginManifest | null;
522
+ /**
523
+ * Resolves a plugin component from a local plugin directory (src/plugins/)
524
+ *
525
+ * @param projectRoot - Project root directory
526
+ * @param pluginName - Name of the plugin
527
+ * @param contractName - Name of the contract to resolve
528
+ * @returns Resolution result with validation messages
529
+ */
530
+ declare function resolveLocalPlugin(projectRoot: string, pluginName: string, contractName: string): WithValidations<PluginComponentResolution> | null;
531
+ /**
532
+ * Resolves a plugin component from an NPM package (node_modules/)
533
+ *
534
+ * @param projectRoot - Project root directory
535
+ * @param pluginName - Name of the NPM package
536
+ * @param contractName - Name of the contract to resolve
537
+ * @returns Resolution result with validation messages
538
+ */
539
+ declare function resolveNpmPlugin(projectRoot: string, pluginName: string, contractName: string): WithValidations<PluginComponentResolution> | null;
540
+ /**
541
+ * Resolves a plugin component, trying local plugins first, then NPM packages
542
+ *
543
+ * @param projectRoot - Project root directory
544
+ * @param pluginName - Name of the plugin
545
+ * @param contractName - Name of the contract to resolve
546
+ * @returns Resolution result with validation messages
547
+ */
548
+ declare function resolvePluginComponent(projectRoot: string, pluginName: string, contractName: string): WithValidations<PluginComponentResolution>;
549
+
550
+ export { CSS_EXTENSION, type CompilerSourceFile, 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_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 };
package/dist/index.js CHANGED
@@ -6,6 +6,9 @@ var __publicField = (obj, key, value) => {
6
6
  };
7
7
  import * as prettier from "prettier";
8
8
  import jsBeautify from "js-beautify";
9
+ import fs from "fs";
10
+ import path from "path";
11
+ import YAML from "yaml";
9
12
  import { createRequire } from "module";
10
13
  const JAY_EXTENSION = ".jay-html";
11
14
  const CSS_EXTENSION = ".css";
@@ -406,6 +409,21 @@ class Imports {
406
409
  return new Imports(newImports);
407
410
  }
408
411
  }
412
+ minus(removeImport) {
413
+ if (removeImport instanceof Imports) {
414
+ let newImports = [...this.imports];
415
+ for (let i2 = 0; i2 < removeImport.imports.length; i2++) {
416
+ if (removeImport.imports[i2]) {
417
+ newImports[i2] = false;
418
+ }
419
+ }
420
+ return new Imports(newImports);
421
+ } else {
422
+ let newImports = [...this.imports];
423
+ newImports[removeImport.index] = false;
424
+ return new Imports(newImports);
425
+ }
426
+ }
409
427
  has(anImport) {
410
428
  return !!this.imports[anImport.index];
411
429
  }
@@ -735,6 +753,133 @@ function withoutExtension(filename, extension) {
735
753
  }
736
754
  return filename.slice(0, -extension.length);
737
755
  }
756
+ var JayBuildEnvironment = /* @__PURE__ */ ((JayBuildEnvironment2) => {
757
+ JayBuildEnvironment2["Client"] = "client";
758
+ JayBuildEnvironment2["Server"] = "server";
759
+ return JayBuildEnvironment2;
760
+ })(JayBuildEnvironment || {});
761
+ const JAY_QUERY_CLIENT = `${JAY_QUERY_PREFIX}${"client"}`;
762
+ const JAY_QUERY_SERVER = `${JAY_QUERY_PREFIX}${"server"}`;
763
+ const JAY_QUERY_PATTERNS = [
764
+ // Build environments
765
+ {
766
+ pattern: `${JAY_QUERY_PREFIX}${"client"}`,
767
+ buildEnv: "client"
768
+ /* Client */
769
+ },
770
+ {
771
+ pattern: `${JAY_QUERY_PREFIX}${"server"}`,
772
+ buildEnv: "server"
773
+ /* Server */
774
+ },
775
+ // Runtime modes (with .ts suffix)
776
+ {
777
+ pattern: `${JAY_QUERY_PREFIX}${RuntimeMode.MainSandbox}${TS_EXTENSION}`,
778
+ runtimeMode: RuntimeMode.MainSandbox
779
+ },
780
+ {
781
+ pattern: `${JAY_QUERY_PREFIX}${RuntimeMode.WorkerTrusted}${TS_EXTENSION}`,
782
+ runtimeMode: RuntimeMode.WorkerTrusted
783
+ },
784
+ {
785
+ pattern: `${JAY_QUERY_PREFIX}${RuntimeMode.WorkerSandbox}${TS_EXTENSION}`,
786
+ runtimeMode: RuntimeMode.WorkerSandbox
787
+ },
788
+ // Runtime modes (without .ts suffix)
789
+ {
790
+ pattern: `${JAY_QUERY_PREFIX}${RuntimeMode.MainSandbox}`,
791
+ runtimeMode: RuntimeMode.MainSandbox
792
+ },
793
+ {
794
+ pattern: `${JAY_QUERY_PREFIX}${RuntimeMode.WorkerTrusted}`,
795
+ runtimeMode: RuntimeMode.WorkerTrusted
796
+ },
797
+ {
798
+ pattern: `${JAY_QUERY_PREFIX}${RuntimeMode.WorkerSandbox}`,
799
+ runtimeMode: RuntimeMode.WorkerSandbox
800
+ }
801
+ ];
802
+ function parseJayModuleSpecifier(specifier) {
803
+ const queryIndex = specifier.indexOf("?");
804
+ if (queryIndex === -1) {
805
+ return {
806
+ basePath: specifier,
807
+ otherQueryParams: "",
808
+ fullQueryString: ""
809
+ };
810
+ }
811
+ const basePath = specifier.substring(0, queryIndex);
812
+ const fullQueryString = specifier.substring(queryIndex);
813
+ let buildEnvironment;
814
+ let runtimeMode;
815
+ let remainingQuery = fullQueryString;
816
+ for (const { pattern, buildEnv, runtimeMode: rtMode } of JAY_QUERY_PATTERNS) {
817
+ if (remainingQuery.includes(pattern)) {
818
+ if (buildEnv)
819
+ buildEnvironment = buildEnv;
820
+ if (rtMode)
821
+ runtimeMode = rtMode;
822
+ remainingQuery = remainingQuery.replace(pattern, "");
823
+ }
824
+ }
825
+ const otherQueryParams = remainingQuery.replace(/^\?&/, "?").replace(/&&/g, "&").replace(/&$/, "").replace(/^\?$/, "");
826
+ return {
827
+ basePath,
828
+ buildEnvironment,
829
+ runtimeMode,
830
+ otherQueryParams,
831
+ fullQueryString
832
+ };
833
+ }
834
+ function addBuildEnvironment(specifier, environment) {
835
+ const parsed = parseJayModuleSpecifier(specifier);
836
+ const jayQuery = `${JAY_QUERY_PREFIX}${environment}`;
837
+ let result = parsed.basePath + jayQuery;
838
+ if (parsed.runtimeMode) {
839
+ result += `${JAY_QUERY_PREFIX}${parsed.runtimeMode}`;
840
+ }
841
+ if (parsed.otherQueryParams) {
842
+ if (parsed.otherQueryParams.startsWith("?")) {
843
+ result += "&" + parsed.otherQueryParams.substring(1);
844
+ } else if (parsed.otherQueryParams) {
845
+ result += "&" + parsed.otherQueryParams;
846
+ }
847
+ }
848
+ return result;
849
+ }
850
+ function hasJayExtension(specifier, extension, { withTs = false } = {}) {
851
+ let normalizedSpecifier = specifier;
852
+ if (withTs) {
853
+ if (specifier.endsWith(TS_EXTENSION)) {
854
+ normalizedSpecifier = specifier.slice(0, -TS_EXTENSION.length);
855
+ } else if (specifier.endsWith(TSX_EXTENSION)) {
856
+ normalizedSpecifier = specifier.slice(0, -TSX_EXTENSION.length);
857
+ }
858
+ }
859
+ let { basePath } = parseJayModuleSpecifier(normalizedSpecifier);
860
+ if (withTs) {
861
+ if (basePath.endsWith(TS_EXTENSION)) {
862
+ basePath = basePath.slice(0, -TS_EXTENSION.length);
863
+ } else if (basePath.endsWith(TSX_EXTENSION)) {
864
+ basePath = basePath.slice(0, -TSX_EXTENSION.length);
865
+ }
866
+ }
867
+ return basePath.endsWith(extension) && basePath.length > extension.length;
868
+ }
869
+ function getBasePath(specifier) {
870
+ return parseJayModuleSpecifier(specifier).basePath;
871
+ }
872
+ function hasBuildEnvironment(specifier) {
873
+ const { buildEnvironment } = parseJayModuleSpecifier(specifier);
874
+ return buildEnvironment !== void 0;
875
+ }
876
+ function getBuildEnvironment(specifier) {
877
+ return parseJayModuleSpecifier(specifier).buildEnvironment;
878
+ }
879
+ function isLocalModule(specifier) {
880
+ const { basePath } = parseJayModuleSpecifier(specifier);
881
+ return basePath.startsWith("./") || basePath.startsWith("../");
882
+ }
738
883
  class WithValidations {
739
884
  constructor(val, validations = []) {
740
885
  __publicField(this, "val");
@@ -811,12 +956,12 @@ function hasRefs(refs, includingAutoRefs) {
811
956
  const allRefs = (ref) => true;
812
957
  return refs.refs.filter(includingAutoRefs ? allRefs : onlyNonAutoRefs).length > 0 || refs.imported || Object.entries(refs.children).map(([ref, refs2]) => hasRefs(refs2, includingAutoRefs)).reduce((prev, curr) => prev || curr, false);
813
958
  }
814
- function nestRefs(path, renderFragment) {
959
+ function nestRefs(path2, renderFragment) {
815
960
  let refs = renderFragment.refs;
816
- for (let index = path.length - 1; index >= 0; --index) {
817
- if (path[index] === ".")
961
+ for (let index = path2.length - 1; index >= 0; --index) {
962
+ if (path2[index] === ".")
818
963
  continue;
819
- refs = mkRefsTree([], { [path[index]]: refs }, refs.repeated);
964
+ refs = mkRefsTree([], { [path2[index]]: refs }, refs.repeated);
820
965
  }
821
966
  return new RenderFragment(
822
967
  renderFragment.rendered,
@@ -938,6 +1083,157 @@ function removeComments(code) {
938
1083
  (line) => !(line.includes("// @ts-expect-error ") || line.includes("// @ts-ignore") || line.includes("{/* @ts-ignore */}"))
939
1084
  ).join("\n");
940
1085
  }
1086
+ const require2 = createRequire(import.meta.url);
1087
+ function loadPluginManifest(pluginDir) {
1088
+ const pluginYamlPath = path.join(pluginDir, "plugin.yaml");
1089
+ if (!fs.existsSync(pluginYamlPath)) {
1090
+ return null;
1091
+ }
1092
+ try {
1093
+ const yamlContent = fs.readFileSync(pluginYamlPath, "utf-8");
1094
+ return YAML.parse(yamlContent);
1095
+ } catch (error) {
1096
+ return null;
1097
+ }
1098
+ }
1099
+ function resolveLocalPlugin(projectRoot, pluginName, contractName) {
1100
+ const localPluginPath = path.join(projectRoot, "src/plugins", pluginName);
1101
+ const pluginYamlPath = path.join(localPluginPath, "plugin.yaml");
1102
+ if (!fs.existsSync(localPluginPath)) {
1103
+ return null;
1104
+ }
1105
+ if (!fs.existsSync(pluginYamlPath)) {
1106
+ return new WithValidations(null, [
1107
+ `Local plugin "${pluginName}" found at ${localPluginPath} but plugin.yaml is missing`
1108
+ ]);
1109
+ }
1110
+ const manifest = loadPluginManifest(localPluginPath);
1111
+ if (!manifest) {
1112
+ return new WithValidations(null, [
1113
+ `Failed to parse plugin.yaml for local plugin "${pluginName}" at ${pluginYamlPath}`
1114
+ ]);
1115
+ }
1116
+ if (!manifest.contracts || manifest.contracts.length === 0) {
1117
+ return new WithValidations(null, [
1118
+ `Local plugin "${pluginName}" has no contracts defined in plugin.yaml`
1119
+ ]);
1120
+ }
1121
+ const contract = manifest.contracts.find((c2) => c2.name === contractName);
1122
+ if (!contract) {
1123
+ const availableContracts = manifest.contracts.map((c2) => c2.name).join(", ");
1124
+ return new WithValidations(null, [
1125
+ `Contract "${contractName}" not found in local plugin "${pluginName}". Available contracts: ${availableContracts}`
1126
+ ]);
1127
+ }
1128
+ const componentModule = manifest.module || "index.js";
1129
+ const componentPath = path.join(localPluginPath, componentModule);
1130
+ return new WithValidations(
1131
+ {
1132
+ contractPath: path.join(localPluginPath, contract.contract),
1133
+ componentPath,
1134
+ componentName: contract.component,
1135
+ // This is the exported member name
1136
+ isNpmPackage: false
1137
+ },
1138
+ []
1139
+ );
1140
+ }
1141
+ function resolveNpmPlugin(projectRoot, pluginName, contractName) {
1142
+ let pluginYamlPath;
1143
+ try {
1144
+ pluginYamlPath = require2.resolve(`${pluginName}/plugin.yaml`, {
1145
+ paths: [projectRoot]
1146
+ });
1147
+ } catch (error) {
1148
+ return new WithValidations(null, [
1149
+ `NPM package "${pluginName}" not found or plugin.yaml is not exported. Is this a Jay Stack plugin?`
1150
+ ]);
1151
+ }
1152
+ const npmPluginPath = path.dirname(pluginYamlPath);
1153
+ if (!fs.existsSync(pluginYamlPath)) {
1154
+ return new WithValidations(null, [
1155
+ `NPM package "${pluginName}" found but plugin.yaml is missing. Is this a Jay Stack plugin?`
1156
+ ]);
1157
+ }
1158
+ const manifest = loadPluginManifest(npmPluginPath);
1159
+ if (!manifest) {
1160
+ return new WithValidations(null, [
1161
+ `Failed to parse plugin.yaml for NPM package "${pluginName}" at ${pluginYamlPath}`
1162
+ ]);
1163
+ }
1164
+ if (!manifest.contracts || manifest.contracts.length === 0) {
1165
+ return new WithValidations(null, [
1166
+ `NPM package "${pluginName}" has no contracts defined in plugin.yaml`
1167
+ ]);
1168
+ }
1169
+ const contract = manifest.contracts.find((c2) => c2.name === contractName);
1170
+ if (!contract) {
1171
+ const availableContracts = manifest.contracts.map((c2) => c2.name).join(", ");
1172
+ return new WithValidations(null, [
1173
+ `Contract "${contractName}" not found in NPM package "${pluginName}". Available contracts: ${availableContracts}`
1174
+ ]);
1175
+ }
1176
+ const packageJsonPath = path.join(npmPluginPath, "package.json");
1177
+ let componentPath;
1178
+ let contractPath;
1179
+ if (fs.existsSync(packageJsonPath)) {
1180
+ try {
1181
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
1182
+ const packageName = packageJson.name;
1183
+ const moduleName = manifest.module || packageName;
1184
+ if ((moduleName === packageName || !manifest.module) && packageJson.exports && packageJson.exports["."]) {
1185
+ const mainExport = packageJson.exports["."];
1186
+ const mainPath = typeof mainExport === "string" ? mainExport : mainExport.default || mainExport.import;
1187
+ componentPath = path.join(npmPluginPath, mainPath);
1188
+ } else {
1189
+ componentPath = path.join(npmPluginPath, "dist/index.js");
1190
+ }
1191
+ const contractSpec = contract.contract;
1192
+ const contractExportKey = "./" + contractSpec;
1193
+ if (packageJson.exports && packageJson.exports[contractExportKey]) {
1194
+ const exportPath = packageJson.exports[contractExportKey];
1195
+ contractPath = path.join(npmPluginPath, exportPath);
1196
+ } else {
1197
+ const possiblePaths = [
1198
+ path.join(npmPluginPath, "dist", contractSpec),
1199
+ path.join(npmPluginPath, "lib", contractSpec),
1200
+ path.join(npmPluginPath, contractSpec)
1201
+ ];
1202
+ contractPath = possiblePaths.find((p) => fs.existsSync(p)) || possiblePaths[0];
1203
+ }
1204
+ } catch (error) {
1205
+ componentPath = path.join(npmPluginPath, "dist/index.js");
1206
+ contractPath = path.join(npmPluginPath, "dist", contract.contract);
1207
+ }
1208
+ } else {
1209
+ componentPath = path.join(npmPluginPath, "dist/index.js");
1210
+ contractPath = path.join(npmPluginPath, "dist", contract.contract);
1211
+ }
1212
+ return new WithValidations(
1213
+ {
1214
+ contractPath,
1215
+ componentPath,
1216
+ componentName: contract.component,
1217
+ // This is the exported member name
1218
+ isNpmPackage: true,
1219
+ packageName: pluginName
1220
+ },
1221
+ []
1222
+ );
1223
+ }
1224
+ function resolvePluginComponent(projectRoot, pluginName, contractName) {
1225
+ const localResult = resolveLocalPlugin(projectRoot, pluginName, contractName);
1226
+ if (localResult !== null) {
1227
+ return localResult;
1228
+ }
1229
+ const npmResult = resolveNpmPlugin(projectRoot, pluginName, contractName);
1230
+ if (npmResult !== null) {
1231
+ return npmResult;
1232
+ }
1233
+ return new WithValidations(null, [
1234
+ `Plugin "${pluginName}" not found. Searched in src/plugins/${pluginName}/ and node_modules/${pluginName}/. Ensure the plugin is installed or exists in your project.`
1235
+ ]);
1236
+ }
941
1237
  const s = createRequire(import.meta.url), e = s("typescript"), u = e, c = new Proxy(e, {
942
1238
  get(t, r) {
943
1239
  return t[r];
@@ -959,9 +1255,11 @@ export {
959
1255
  JAY_DTS_EXTENSION,
960
1256
  JAY_EXTENSION,
961
1257
  JAY_FULLSTACK_COMPONENTS,
1258
+ JAY_QUERY_CLIENT,
962
1259
  JAY_QUERY_MAIN_SANDBOX,
963
1260
  JAY_QUERY_MAIN_SANDBOX_TS,
964
1261
  JAY_QUERY_PREFIX,
1262
+ JAY_QUERY_SERVER,
965
1263
  JAY_QUERY_WORKER_SANDBOX,
966
1264
  JAY_QUERY_WORKER_SANDBOX_TS,
967
1265
  JAY_QUERY_WORKER_TRUSTED,
@@ -972,6 +1270,7 @@ export {
972
1270
  JayArrayType,
973
1271
  JayAtomicType,
974
1272
  JayBoolean,
1273
+ JayBuildEnvironment,
975
1274
  JayComponentApiMember,
976
1275
  JayComponentType,
977
1276
  JayDate,
@@ -1000,14 +1299,19 @@ export {
1000
1299
  TSX_EXTENSION,
1001
1300
  TS_EXTENSION,
1002
1301
  WithValidations,
1302
+ addBuildEnvironment,
1003
1303
  checkValidationErrors,
1004
1304
  equalJayTypes,
1305
+ getBasePath,
1306
+ getBuildEnvironment,
1005
1307
  getJayTsFileSourcePath,
1006
1308
  getMode,
1007
1309
  getModeFileExtension,
1008
1310
  getModeFromExtension,
1009
1311
  i as getTs,
1312
+ hasBuildEnvironment,
1010
1313
  hasExtension,
1314
+ hasJayExtension,
1011
1315
  hasJayModeExtension,
1012
1316
  hasRefs,
1013
1317
  isArrayType,
@@ -1020,18 +1324,24 @@ export {
1020
1324
  isEnumType,
1021
1325
  isHTMLType,
1022
1326
  isImportedType,
1327
+ isLocalModule,
1023
1328
  isObjectType,
1024
1329
  isPromiseType,
1025
1330
  isRecursiveType,
1026
1331
  isTypeAliasType,
1027
1332
  isUnionType,
1333
+ loadPluginManifest,
1028
1334
  mergeRefsTrees,
1029
1335
  mkRef,
1030
1336
  mkRefsTree,
1031
1337
  nestRefs,
1338
+ parseJayModuleSpecifier,
1032
1339
  prettify,
1033
1340
  prettifyHtml,
1034
1341
  removeComments,
1342
+ resolveLocalPlugin,
1343
+ resolveNpmPlugin,
1344
+ resolvePluginComponent,
1035
1345
  resolvePrimitiveType,
1036
1346
  u as ts,
1037
1347
  c as tsBridge,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jay-framework/compiler-shared",
3
- "version": "0.8.0",
3
+ "version": "0.10.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.8.0",
29
- "@jay-framework/runtime": "^0.8.0",
30
- "@jay-framework/secure": "^0.8.0",
31
- "@jay-framework/typescript-bridge": "^0.3.0",
28
+ "@jay-framework/component": "^0.10.0",
29
+ "@jay-framework/runtime": "^0.10.0",
30
+ "@jay-framework/secure": "^0.10.0",
31
+ "@jay-framework/typescript-bridge": "^0.5.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.8.0",
44
+ "@jay-framework/dev-environment": "^0.10.0",
45
45
  "@testing-library/jest-dom": "^6.2.0",
46
46
  "@types/js-beautify": "^1",
47
47
  "@types/node": "^20.11.5",