@meridianjs/framework 0.1.1 → 0.1.3

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.
Files changed (2) hide show
  1. package/dist/index.js +110 -98
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -138,9 +138,9 @@ async function resolveModuleDefinition(config, rootDir) {
138
138
  }
139
139
 
140
140
  // src/plugin-loader.ts
141
- import path6 from "path";
142
- import fs4 from "fs/promises";
143
- import { pathToFileURL as pathToFileURL6 } from "url";
141
+ import path7 from "path";
142
+ import fs5 from "fs/promises";
143
+ import { pathToFileURL as pathToFileURL7 } from "url";
144
144
  import { createRequire } from "module";
145
145
 
146
146
  // src/route-loader.ts
@@ -316,13 +316,94 @@ async function loadJobs(container, jobsDir) {
316
316
  }
317
317
  }
318
318
 
319
+ // src/link-loader.ts
320
+ import fs4 from "fs/promises";
321
+ import path6 from "path";
322
+ import { pathToFileURL as pathToFileURL6 } from "url";
323
+ async function loadLinks(container, linksDir) {
324
+ const logger = container.resolve("logger");
325
+ const definitions = [];
326
+ try {
327
+ await fs4.access(linksDir);
328
+ } catch {
329
+ logger.debug(`No links directory at ${linksDir}, skipping.`);
330
+ registerEmptyServices(container);
331
+ return;
332
+ }
333
+ const files = await fs4.readdir(linksDir);
334
+ for (const file of files) {
335
+ if (!/\.(ts|mts|js|mjs|cjs)$/.test(file)) continue;
336
+ const fullPath = path6.join(linksDir, file);
337
+ let mod;
338
+ try {
339
+ mod = await import(pathToFileURL6(fullPath).href);
340
+ } catch (err) {
341
+ logger.error(`Failed to load link file ${file}: ${err.message}`);
342
+ continue;
343
+ }
344
+ const def = mod.default;
345
+ if (def?.linkTableName) {
346
+ definitions.push(def);
347
+ logger.debug(`Link loaded: ${def.linkTableName}`);
348
+ }
349
+ }
350
+ let existingDefs = [];
351
+ try {
352
+ const existingLink = container.resolve("link");
353
+ existingDefs = existingLink.getDefinitions?.() ?? [];
354
+ } catch {
355
+ }
356
+ const allDefs = [...existingDefs, ...definitions];
357
+ const linkService = new LinkService(allDefs, container, logger);
358
+ const queryService = new QueryService(allDefs, container, logger);
359
+ container.register({
360
+ link: linkService,
361
+ query: queryService
362
+ });
363
+ logger.info(`Loaded ${allDefs.length} module link(s)`);
364
+ }
365
+ function registerEmptyServices(container) {
366
+ const link = new LinkService([], container, null);
367
+ const query = new QueryService([], container, null);
368
+ container.register({ link, query });
369
+ }
370
+ var LinkService = class {
371
+ constructor(defs, container, logger) {
372
+ this.defs = defs;
373
+ this.container = container;
374
+ this.logger = logger;
375
+ this.defsByTable = new Map(defs.map((d) => [d.linkTableName, d]));
376
+ }
377
+ defsByTable;
378
+ async create(linkTableName, leftId, rightId, data) {
379
+ this.logger?.debug(`Link.create: ${linkTableName} ${leftId} \u2192 ${rightId}`);
380
+ }
381
+ async dismiss(linkTableName, leftId, rightId) {
382
+ this.logger?.debug(`Link.dismiss: ${linkTableName} ${leftId} \u2192 ${rightId}`);
383
+ }
384
+ getDefinitions() {
385
+ return this.defs;
386
+ }
387
+ };
388
+ var QueryService = class {
389
+ constructor(defs, container, logger) {
390
+ this.defs = defs;
391
+ this.container = container;
392
+ this.logger = logger;
393
+ }
394
+ async graph(options) {
395
+ this.logger?.debug(`Query.graph: ${options.entity}`, { fields: options.fields });
396
+ return { data: [] };
397
+ }
398
+ };
399
+
319
400
  // src/plugin-loader.ts
320
401
  async function loadPlugins(container, plugins, rootDir) {
321
402
  const logger = container.resolve("logger");
322
403
  for (const plugin of plugins) {
323
404
  logger.info(`Loading plugin: ${plugin.resolve}`);
324
- const isLocalPath = plugin.resolve.startsWith(".") || path6.isAbsolute(plugin.resolve);
325
- const importPath = isLocalPath ? pathToFileURL6(path6.resolve(rootDir, plugin.resolve)).href : plugin.resolve;
405
+ const isLocalPath = plugin.resolve.startsWith(".") || path7.isAbsolute(plugin.resolve);
406
+ const importPath = isLocalPath ? pathToFileURL7(path7.resolve(rootDir, plugin.resolve)).href : plugin.resolve;
326
407
  let pluginMod;
327
408
  try {
328
409
  pluginMod = await import(importPath);
@@ -334,12 +415,12 @@ async function loadPlugins(container, plugins, rootDir) {
334
415
  if (pluginMod.pluginRoot && typeof pluginMod.pluginRoot === "string") {
335
416
  scanRoot = pluginMod.pluginRoot;
336
417
  } else if (isLocalPath) {
337
- const resolvedPath = path6.resolve(rootDir, plugin.resolve);
418
+ const resolvedPath = path7.resolve(rootDir, plugin.resolve);
338
419
  try {
339
- const stat = await fs4.stat(resolvedPath);
340
- scanRoot = stat.isDirectory() ? resolvedPath : path6.dirname(resolvedPath);
420
+ const stat = await fs5.stat(resolvedPath);
421
+ scanRoot = stat.isDirectory() ? resolvedPath : path7.dirname(resolvedPath);
341
422
  } catch {
342
- scanRoot = path6.dirname(resolvedPath);
423
+ scanRoot = path7.dirname(resolvedPath);
343
424
  }
344
425
  } else {
345
426
  scanRoot = resolveNpmPackageRoot(plugin.resolve, rootDir);
@@ -366,23 +447,28 @@ async function loadPlugins(container, plugins, rootDir) {
366
447
  }
367
448
  }
368
449
  async function autoScanPlugin(scanRoot, container, logger) {
369
- const server = container.resolve("server");
450
+ let server = null;
451
+ try {
452
+ server = container.resolve("server");
453
+ } catch {
454
+ }
370
455
  const candidates = [
371
456
  scanRoot,
372
457
  // pluginRoot already points to compiled dir
373
- path6.join(scanRoot, "dist"),
458
+ path7.join(scanRoot, "dist"),
374
459
  // package root → try dist/ first
375
- path6.join(scanRoot, "src")
460
+ path7.join(scanRoot, "src")
376
461
  // package root → try src/ (tsx dev mode)
377
462
  ];
378
463
  for (const candidate of candidates) {
379
- const apiDir = path6.join(candidate, "api");
464
+ const apiDir = path7.join(candidate, "api");
380
465
  try {
381
- await fs4.access(apiDir);
466
+ await fs5.access(apiDir);
382
467
  await Promise.all([
383
- loadRoutes(server, container, apiDir),
384
- loadSubscribers(container, path6.join(candidate, "subscribers")),
385
- loadJobs(container, path6.join(candidate, "jobs"))
468
+ server ? loadRoutes(server, container, apiDir) : Promise.resolve(),
469
+ loadSubscribers(container, path7.join(candidate, "subscribers")),
470
+ loadJobs(container, path7.join(candidate, "jobs")),
471
+ loadLinks(container, path7.join(candidate, "links"))
386
472
  ]);
387
473
  logger.debug(`Plugin auto-scanned from: ${candidate}`);
388
474
  return;
@@ -393,20 +479,20 @@ async function autoScanPlugin(scanRoot, container, logger) {
393
479
  }
394
480
  function resolveNpmPackageRoot(packageName, fromDir) {
395
481
  try {
396
- const require2 = createRequire(path6.join(fromDir, "synthetic.cjs"));
482
+ const require2 = createRequire(path7.join(fromDir, "synthetic.cjs"));
397
483
  const pkgJsonPath = require2.resolve(`${packageName}/package.json`);
398
- return path6.dirname(pkgJsonPath);
484
+ return path7.dirname(pkgJsonPath);
399
485
  } catch {
400
486
  try {
401
- const require2 = createRequire(path6.join(fromDir, "synthetic.cjs"));
487
+ const require2 = createRequire(path7.join(fromDir, "synthetic.cjs"));
402
488
  const mainPath = require2.resolve(packageName);
403
- let dir = path6.dirname(mainPath);
404
- while (dir !== path6.dirname(dir)) {
489
+ let dir = path7.dirname(mainPath);
490
+ while (dir !== path7.dirname(dir)) {
405
491
  try {
406
- require2.resolve(path6.join(dir, "package.json"));
492
+ require2.resolve(path7.join(dir, "package.json"));
407
493
  return dir;
408
494
  } catch {
409
- dir = path6.dirname(dir);
495
+ dir = path7.dirname(dir);
410
496
  }
411
497
  }
412
498
  } catch {
@@ -415,80 +501,6 @@ function resolveNpmPackageRoot(packageName, fromDir) {
415
501
  }
416
502
  }
417
503
 
418
- // src/link-loader.ts
419
- import fs5 from "fs/promises";
420
- import path7 from "path";
421
- import { pathToFileURL as pathToFileURL7 } from "url";
422
- async function loadLinks(container, linksDir) {
423
- const logger = container.resolve("logger");
424
- const definitions = [];
425
- try {
426
- await fs5.access(linksDir);
427
- } catch {
428
- logger.debug(`No links directory at ${linksDir}, skipping.`);
429
- registerEmptyServices(container);
430
- return;
431
- }
432
- const files = await fs5.readdir(linksDir);
433
- for (const file of files) {
434
- if (!/\.(ts|mts|js|mjs|cjs)$/.test(file)) continue;
435
- const fullPath = path7.join(linksDir, file);
436
- let mod;
437
- try {
438
- mod = await import(pathToFileURL7(fullPath).href);
439
- } catch (err) {
440
- logger.error(`Failed to load link file ${file}: ${err.message}`);
441
- continue;
442
- }
443
- const def = mod.default;
444
- if (def?.linkTableName) {
445
- definitions.push(def);
446
- logger.debug(`Link loaded: ${def.linkTableName}`);
447
- }
448
- }
449
- const linkService = new LinkService(definitions, container, logger);
450
- const queryService = new QueryService(definitions, container, logger);
451
- container.register({
452
- link: linkService,
453
- query: queryService
454
- });
455
- logger.info(`Loaded ${definitions.length} module link(s)`);
456
- }
457
- function registerEmptyServices(container) {
458
- const link = new LinkService([], container, null);
459
- const query = new QueryService([], container, null);
460
- container.register({ link, query });
461
- }
462
- var LinkService = class {
463
- constructor(defs, container, logger) {
464
- this.defs = defs;
465
- this.container = container;
466
- this.logger = logger;
467
- this.defsByTable = new Map(defs.map((d) => [d.linkTableName, d]));
468
- }
469
- defsByTable;
470
- async create(linkTableName, leftId, rightId, data) {
471
- this.logger?.debug(`Link.create: ${linkTableName} ${leftId} \u2192 ${rightId}`);
472
- }
473
- async dismiss(linkTableName, leftId, rightId) {
474
- this.logger?.debug(`Link.dismiss: ${linkTableName} ${leftId} \u2192 ${rightId}`);
475
- }
476
- getDefinitions() {
477
- return this.defs;
478
- }
479
- };
480
- var QueryService = class {
481
- constructor(defs, container, logger) {
482
- this.defs = defs;
483
- this.container = container;
484
- this.logger = logger;
485
- }
486
- async graph(options) {
487
- this.logger?.debug(`Query.graph: ${options.entity}`, { fields: options.fields });
488
- return { data: [] };
489
- }
490
- };
491
-
492
504
  // src/server.ts
493
505
  import express from "express";
494
506
  import cors from "cors";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meridianjs/framework",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "Core Meridian framework: bootstrap, DI container, module/route/subscriber/job loaders",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",