@atscript/typescript 0.1.90 → 0.1.91

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/cli.cjs CHANGED
@@ -1606,6 +1606,12 @@ const QUERY_OP_MAP = {
1606
1606
  "not exists": "$exists"
1607
1607
  };
1608
1608
  var JsRenderer = class extends BaseRenderer {
1609
+ /**
1610
+ * Relative imports get the configured `moduleExtension`; bare specifiers
1611
+ * always keep `.as` — they resolve through the package's `exports` map.
1612
+ */ transformFromPath(path) {
1613
+ return (0, _atscript_core.isBareSpecifier)(path) ? `${path}.as` : `${path}${this.opts?.moduleExtension ?? ".as"}`;
1614
+ }
1609
1615
  /**
1610
1616
  * Override base `unused` to subtract symbols that the JS output references
1611
1617
  * transitively through `extends`-resolved parent prop trees. Without this,
@@ -2518,6 +2524,30 @@ async function getConfig(configFile, logger) {
2518
2524
  }
2519
2525
  }
2520
2526
 
2527
+ //#endregion
2528
+ //#region packages/typescript/src/cli/diagnostics.ts
2529
+ /**
2530
+ * Runs the builder's diagnostics and renders every message the way the
2531
+ * default `asc` command prints it. Shared by `asc` and `asc db sync` so both
2532
+ * commands count and format diagnostics identically.
2533
+ */ async function collectDiagnostics(builder) {
2534
+ const summary = {
2535
+ errors: 0,
2536
+ warnings: 0,
2537
+ messages: []
2538
+ };
2539
+ const diagMap = await builder.diagnostics();
2540
+ for (const [docId, messages] of diagMap) {
2541
+ const doc = builder.getDoc(docId);
2542
+ for (const m of messages) {
2543
+ if (m.severity === 1) summary.errors++;
2544
+ else if (m.severity === 2) summary.warnings++;
2545
+ if (doc) summary.messages.push(doc.renderDiagMessage(m, true, true));
2546
+ }
2547
+ }
2548
+ return summary;
2549
+ }
2550
+
2521
2551
  //#endregion
2522
2552
  //#region packages/typescript/src/cli/emit-policy.ts
2523
2553
  /**
@@ -2525,16 +2555,16 @@ async function getConfig(configFile, logger) {
2525
2555
  * user knows the previous outputs are still the last known-good ones.
2526
2556
  */ const NOTHING_EMITTED_MESSAGE = "Nothing emitted — previous outputs were left untouched. Fix the errors above, or pass --skipDiag to emit anyway.";
2527
2557
  /**
2528
- * Decides whether `asc` may write its outputs.
2558
+ * Decides whether `asc` may write its outputs — and, when it may not, why.
2529
2559
  *
2530
2560
  * A failing compile must never replace valid artifacts: half of the outputs
2531
2561
  * would be stale and aggregate manifests produced in `buildEnd` would be
2532
2562
  * regenerated from an incomplete document set. Errors therefore block the
2533
2563
  * write entirely — `--skipDiag` is the explicit opt-out.
2534
- */ function shouldEmit(input) {
2535
- if (input.noEmit) return false;
2536
- if (input.skipDiag) return true;
2537
- return input.errorCount === 0;
2564
+ */ function emitDecision(input) {
2565
+ if (input.noEmit) return "noEmit";
2566
+ if (input.skipDiag || input.errorCount === 0) return "emit";
2567
+ return "blocked";
2538
2568
  }
2539
2569
 
2540
2570
  //#endregion
@@ -2572,22 +2602,17 @@ var Commands = class {
2572
2602
  let errorCount = 0;
2573
2603
  let warningCount = 0;
2574
2604
  if (!skipDiag) {
2575
- const diagMap = await builder.diagnostics();
2576
- for (const [docId, messages] of diagMap) {
2577
- const doc = builder.getDoc(docId);
2578
- for (const m of messages) {
2579
- if (m.severity === 1) errorCount++;
2580
- else if (m.severity === 2) warningCount++;
2581
- if (doc) this.logger.log(doc.renderDiagMessage(m, true, true));
2582
- }
2583
- }
2605
+ const diagnostics = await collectDiagnostics(builder);
2606
+ for (const message of diagnostics.messages) this.logger.log(message);
2607
+ errorCount = diagnostics.errors;
2608
+ warningCount = diagnostics.warnings;
2584
2609
  }
2585
- const emit = shouldEmit({
2610
+ const decision = emitDecision({
2586
2611
  noEmit,
2587
2612
  skipDiag,
2588
2613
  errorCount
2589
2614
  });
2590
- if (emit) {
2615
+ if (decision === "emit") {
2591
2616
  const out = await builder.write(config);
2592
2617
  for (const { target } of out) this.logger.log(`✅ created ${target}`);
2593
2618
  }
@@ -2597,10 +2622,8 @@ var Commands = class {
2597
2622
  if (warningCount > 0) parts.push(`${warningCount} warning${warningCount > 1 ? "s" : ""}`);
2598
2623
  this.logger.log(`\nFound ${parts.join(" and ")}`);
2599
2624
  }
2600
- if (errorCount > 0) {
2601
- if (!emit && !noEmit) this.logger.log(`${NOTHING_EMITTED_MESSAGE}`);
2602
- process.exit(1);
2603
- }
2625
+ if (decision === "blocked") this.logger.log(`${NOTHING_EMITTED_MESSAGE}`);
2626
+ if (errorCount > 0) process.exit(1);
2604
2627
  }
2605
2628
  constructor(logger) {
2606
2629
  _define_property$2(this, "logger", void 0);
@@ -2644,8 +2667,6 @@ Commands = _ts_decorate$1([
2644
2667
 
2645
2668
  //#endregion
2646
2669
  //#region packages/typescript/src/cli/db-sync-models.ts
2647
- /** Depth cap for `config.models` — deep enough for nested arrays and namespaces. */ const MAX_MODELS_DEPTH = 6;
2648
- /** Keeps two runs in the same process (and the same millisecond) apart. */ let runSeq = 0;
2649
2670
  /**
2650
2671
  * Compiles the project's `.as` files and loads every `@db.table` / `@db.view`
2651
2672
  * model, plus the models contributed by `config.models`.
@@ -2654,10 +2675,10 @@ Commands = _ts_decorate$1([
2654
2675
  * both `failures` and `modelsError` are empty — a caller that plans a sync
2655
2676
  * from a partial inventory would propose dropping the tables it failed to see.
2656
2677
  */ async function loadDbModels(options) {
2657
- const { config, cwd = process.cwd(), logger } = options;
2678
+ const { config, cwd = process.cwd() } = options;
2658
2679
  const buildConfig = toBuildConfig(config);
2659
- logger?.log(`Compiling .as files...`);
2660
2680
  const builder = await (0, _atscript_core.build)(buildConfig);
2681
+ const rootDir = buildConfig.rootDir;
2661
2682
  const diagnostics = await collectDiagnostics(builder);
2662
2683
  if (diagnostics.errors > 0) return {
2663
2684
  types: [],
@@ -2665,7 +2686,7 @@ Commands = _ts_decorate$1([
2665
2686
  diagnostics,
2666
2687
  packaged: 0
2667
2688
  };
2668
- const { types, failures } = await importGeneratedModules(await builder.generate(buildConfig), buildConfig.rootDir || cwd, cwd);
2689
+ const { types, failures } = await importGeneratedModules(await builder.generate(buildConfig), rootDir, cwd);
2669
2690
  const result = {
2670
2691
  types,
2671
2692
  failures,
@@ -2674,20 +2695,14 @@ Commands = _ts_decorate$1([
2674
2695
  };
2675
2696
  if (failures.length > 0 || !config.models) return result;
2676
2697
  try {
2677
- const seen = new Set(types);
2678
- for (const model of flattenModels(await config.models())) if (!seen.has(model)) {
2679
- seen.add(model);
2680
- types.push(model);
2681
- result.packaged++;
2682
- }
2698
+ const models = flattenModels(await config.models());
2699
+ types.push(...models);
2700
+ result.packaged = models.length;
2683
2701
  } catch (error) {
2684
2702
  result.modelsError = error;
2685
2703
  }
2686
2704
  return result;
2687
2705
  }
2688
- /** Abort message printed when some generated modules could not be imported. */ function partialInventoryMessage(count) {
2689
- return `Could not load ${count} compiled model module(s); aborting before planning — a partial inventory would propose dropping tables.`;
2690
- }
2691
2706
  function errorMessage(error) {
2692
2707
  return error instanceof Error ? error.message : String(error);
2693
2708
  }
@@ -2697,12 +2712,9 @@ function errorMessage(error) {
2697
2712
  * nesting of those. Deduplicated by identity.
2698
2713
  */ function flattenModels(value) {
2699
2714
  const out = [];
2700
- walkModels(value, out, /* @__PURE__ */ new Set(), 0);
2715
+ walkModels(value, out, /* @__PURE__ */ new Set());
2701
2716
  return out;
2702
2717
  }
2703
- /** Rewrites the emitted `.as` specifiers to the `.mjs` files we just wrote. */ function patchAsImports(content) {
2704
- return content.replace(/(from\s+["'][^"']+)\.as(["'])/g, "$1.as.mjs$2");
2705
- }
2706
2718
  function toBuildConfig(config) {
2707
2719
  const buildConfig = { ...config };
2708
2720
  if (typeof config.db === "object" && "adapter" in config.db) {
@@ -2711,34 +2723,20 @@ function toBuildConfig(config) {
2711
2723
  if (dbConfig.exclude) buildConfig.exclude = dbConfig.exclude;
2712
2724
  }
2713
2725
  buildConfig.format = "js";
2726
+ const syncTs = tsPlugin({ moduleExtension: ".as.mjs" });
2727
+ const plugins = (config.plugins ?? []).map((p) => p.name === "typescript" ? syncTs : p);
2728
+ if (!plugins.includes(syncTs)) plugins.push(syncTs);
2729
+ buildConfig.plugins = plugins;
2714
2730
  return buildConfig;
2715
2731
  }
2716
- async function collectDiagnostics(builder) {
2717
- const diagnostics = {
2718
- errors: 0,
2719
- warnings: 0,
2720
- messages: []
2721
- };
2722
- const diagMap = await builder.diagnostics();
2723
- for (const [docId, messages] of diagMap) {
2724
- const doc = builder.getDoc(docId);
2725
- for (const m of messages) {
2726
- if (m.severity === 1) diagnostics.errors++;
2727
- else if (m.severity === 2) diagnostics.warnings++;
2728
- if (doc) diagnostics.messages.push(doc.renderDiagMessage(m, true, true));
2729
- }
2730
- }
2731
- return diagnostics;
2732
- }
2733
2732
  async function importGeneratedModules(outputs, rootDir, cwd) {
2734
- const jsOutputs = [];
2735
- for (const o of outputs) if (o.fileName.endsWith(".js") && o.source) jsOutputs.push({
2736
- fileName: o.fileName,
2737
- content: o.content,
2738
- source: o.source
2739
- });
2740
- const base = resolveLayoutBase(rootDir, jsOutputs.map((o) => path.default.dirname((0, _atscript_core.fileUriToPath)(o.source))));
2741
- const tmpDir = path.default.join(cwd, `.atscript-db-sync-${process.pid}-${Date.now()}-${runSeq++}`);
2733
+ const modules = outputs.filter((o) => o.fileName.endsWith(".js")).map((o) => ({
2734
+ srcDir: path.default.dirname((0, _atscript_core.fileUriToPath)(o.source)),
2735
+ fileName: o.fileName.replace(/\.js$/, ".mjs"),
2736
+ content: o.content
2737
+ }));
2738
+ const base = commonAncestor([rootDir, ...modules.map((m) => m.srcDir)]);
2739
+ const tmpDir = (0, fs.mkdtempSync)(path.default.join(cwd, ".atscript-db-sync-"));
2742
2740
  const cleanup = () => {
2743
2741
  try {
2744
2742
  (0, fs.rmSync)(tmpDir, {
@@ -2750,12 +2748,16 @@ async function importGeneratedModules(outputs, rootDir, cwd) {
2750
2748
  process.on("exit", cleanup);
2751
2749
  try {
2752
2750
  const files = [];
2753
- for (const o of jsOutputs) {
2754
- const srcDir = path.default.dirname((0, _atscript_core.fileUriToPath)(o.source));
2755
- const rel = path.default.join(path.default.relative(base, srcDir), o.fileName.replace(/\.js$/, ".mjs"));
2751
+ const dirs = /* @__PURE__ */ new Set();
2752
+ for (const m of modules) {
2753
+ const rel = path.default.join(path.default.relative(base, m.srcDir), m.fileName);
2756
2754
  const abs = path.default.join(tmpDir, rel);
2757
- (0, fs.mkdirSync)(path.default.dirname(abs), { recursive: true });
2758
- (0, fs.writeFileSync)(abs, patchAsImports(o.content));
2755
+ const dir = path.default.dirname(abs);
2756
+ if (!dirs.has(dir)) {
2757
+ dirs.add(dir);
2758
+ (0, fs.mkdirSync)(dir, { recursive: true });
2759
+ }
2760
+ (0, fs.writeFileSync)(abs, m.content);
2759
2761
  files.push({
2760
2762
  abs,
2761
2763
  rel
@@ -2765,7 +2767,7 @@ async function importGeneratedModules(outputs, rootDir, cwd) {
2765
2767
  const failures = [];
2766
2768
  const seen = /* @__PURE__ */ new Set();
2767
2769
  for (const file of files) try {
2768
- collectFromModule(await import(
2770
+ walkModels(await import(
2769
2771
  /* @vite-ignore */
2770
2772
  (0, node_url.pathToFileURL)(file.abs).href
2771
2773
  ), types, seen);
@@ -2784,24 +2786,11 @@ async function importGeneratedModules(outputs, rootDir, cwd) {
2784
2786
  process.off("exit", cleanup);
2785
2787
  }
2786
2788
  }
2787
- function collectFromModule(mod, types, seen) {
2788
- for (const exp of Object.values(mod)) if (isDbModel(exp) && !seen.has(exp)) {
2789
- seen.add(exp);
2790
- types.push(exp);
2791
- }
2792
- }
2793
2789
  /**
2794
- * Directory the temp layout mirrors. Normally `rootDir`; when a source lives
2795
- * outside it, the common ancestor of `rootDir` and every source, so that no
2796
- * `..` segment ever escapes the temp directory.
2797
- */ function resolveLayoutBase(rootDir, sourceDirs) {
2798
- const root = path.default.resolve(rootDir);
2799
- return sourceDirs.some((dir) => {
2800
- const rel = path.default.relative(root, path.default.resolve(dir));
2801
- return rel === ".." || rel.startsWith(`..${path.default.sep}`);
2802
- }) ? commonAncestor([root, ...sourceDirs]) : root;
2803
- }
2804
- function commonAncestor(dirs) {
2790
+ * Directory the temp layout mirrors: the common ancestor of `rootDir` and
2791
+ * every source directory — `rootDir` itself when every source lives under it —
2792
+ * so that no `..` segment ever escapes the temp directory.
2793
+ */ function commonAncestor(dirs) {
2805
2794
  const parts = dirs.map((d) => path.default.resolve(d).split(path.default.sep));
2806
2795
  const first = parts[0];
2807
2796
  let i = 0;
@@ -2811,7 +2800,7 @@ function commonAncestor(dirs) {
2811
2800
  function isDbModel(value) {
2812
2801
  return isAnnotatedType(value) && Boolean(value.metadata?.has("db.table") || value.metadata?.has("db.view"));
2813
2802
  }
2814
- function walkModels(value, out, seen, depth) {
2803
+ /** `seen` deduplicates by identity and guarantees termination on cyclic graphs. */ function walkModels(value, out, seen) {
2815
2804
  if (!value || typeof value !== "object" && typeof value !== "function") return;
2816
2805
  if (seen.has(value)) return;
2817
2806
  seen.add(value);
@@ -2819,9 +2808,8 @@ function walkModels(value, out, seen, depth) {
2819
2808
  if (isDbModel(value)) out.push(value);
2820
2809
  return;
2821
2810
  }
2822
- if (depth >= MAX_MODELS_DEPTH) return;
2823
2811
  const items = Array.isArray(value) ? value : Object.values(value);
2824
- for (const item of items) walkModels(item, out, seen, depth + 1);
2812
+ for (const item of items) walkModels(item, out, seen);
2825
2813
  }
2826
2814
 
2827
2815
  //#endregion
@@ -3008,18 +2996,16 @@ var DbSyncController = class {
3008
2996
  info(message) {
3009
2997
  if (!this.quiet) this.logger.log(message);
3010
2998
  }
2999
+ /** Prints each line in red and exits 1. */ fail(...lines) {
3000
+ for (const line of lines) this.logger.error(`${line}`);
3001
+ process.exit(1);
3002
+ }
3011
3003
  async dbSync(configFile, dryRun, yes, force, safe, check, format, out) {
3012
- if (format && format !== "json" && format !== "markdown") {
3013
- this.logger.error(`Unknown --format "${format}". Use "json" or "markdown".`);
3014
- process.exit(1);
3015
- }
3004
+ if (format && format !== "json" && format !== "markdown") this.fail(`Unknown --format "${format}". Use "json" or "markdown".`);
3016
3005
  this.quiet = Boolean(format) && !out;
3017
3006
  this.printer.muted = this.quiet;
3018
3007
  const config = await getConfig(configFile, this.quiet ? Object.create(this.logger, { log: { value: () => {} } }) : this.logger);
3019
- if (!config.db) {
3020
- this.logger.error("\x1B[31mNo \"db\" field in atscript config. Add a db configuration to use schema sync.\x1B[39m");
3021
- process.exit(1);
3022
- }
3008
+ if (!config.db) this.fail("No \"db\" field in atscript config. Add a db configuration to use schema sync.");
3023
3009
  const dbTypes = await this.loadTypes(config);
3024
3010
  if (dbTypes.length === 0) {
3025
3011
  this.info(`No types with @db.table or @db.view found. Nothing to sync.`);
@@ -3045,10 +3031,7 @@ var DbSyncController = class {
3045
3031
  if (plan.status === "up-to-date") this.printer.planUpToDate(plan);
3046
3032
  else {
3047
3033
  this.printer.plan(plan);
3048
- if (hasErrors) {
3049
- this.logger.error(`Schema has errors. Fix the issues above before syncing.`);
3050
- process.exit(1);
3051
- }
3034
+ if (hasErrors) this.fail("Schema has errors. Fix the issues above before syncing.");
3052
3035
  }
3053
3036
  if (check || format) {
3054
3037
  if (check && hasChanges) {
@@ -3088,26 +3071,15 @@ var DbSyncController = class {
3088
3071
  * generated module is imported individually, and any failure exits 1 before
3089
3072
  * a plan is computed.
3090
3073
  */ async loadTypes(config) {
3091
- const result = await loadDbModels({
3092
- config,
3093
- cwd: process.cwd(),
3094
- logger: { log: (message) => this.info(message) }
3095
- });
3074
+ this.info(`Compiling .as files...`);
3075
+ const result = await loadDbModels({ config });
3096
3076
  if (result.diagnostics.errors > 0) {
3097
3077
  for (const message of result.diagnostics.messages) this.logger.error(message);
3098
- this.logger.error(`Fix the errors above before syncing.`);
3099
- process.exit(1);
3078
+ this.fail("Fix the errors above before syncing.");
3100
3079
  }
3101
3080
  for (const message of result.diagnostics.messages) this.info(message);
3102
- if (result.failures.length > 0) {
3103
- for (const failure of result.failures) this.logger.error(`✖ ${failure.file}: ${errorMessage(failure.error)}`);
3104
- this.logger.error(`${partialInventoryMessage(result.failures.length)}`);
3105
- process.exit(1);
3106
- }
3107
- if (result.modelsError) {
3108
- this.logger.error(`config.models failed: ${errorMessage(result.modelsError)}`);
3109
- process.exit(1);
3110
- }
3081
+ if (result.failures.length > 0) this.fail(...result.failures.map((f) => `✖ ${f.file}: ${errorMessage(f.error)}`), `Could not load ${result.failures.length} compiled model module(s); aborting before planning — a partial inventory would propose dropping tables.`);
3082
+ if (result.modelsError) this.fail(`config.models failed: ${errorMessage(result.modelsError)}`);
3111
3083
  if (result.packaged > 0) this.info(`Loaded ${result.packaged} packaged model(s) from config.models`);
3112
3084
  return result.types;
3113
3085
  }
@@ -3122,13 +3094,9 @@ var DbSyncController = class {
3122
3094
  try {
3123
3095
  mod = await this.importFromCwd(adapter);
3124
3096
  } catch {
3125
- this.logger.error(`Could not import adapter package "${adapter}". Is it installed?`);
3126
- process.exit(1);
3127
- }
3128
- if (typeof mod.createAdapter !== "function") {
3129
- this.logger.error(`Adapter package "${adapter}" does not export a createAdapter function.`);
3130
- process.exit(1);
3097
+ this.fail(`Could not import adapter package "${adapter}". Is it installed?`);
3131
3098
  }
3099
+ if (typeof mod.createAdapter !== "function") this.fail(`Adapter package "${adapter}" does not export a createAdapter function.`);
3132
3100
  const resolvedConnection = typeof connection === "function" ? await connection() : connection;
3133
3101
  return mod.createAdapter(resolvedConnection, options);
3134
3102
  }
package/dist/index.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } });
2
- const require_plugin = require('./plugin-Cs9mKJ8h.cjs');
2
+ const require_plugin = require('./plugin-BYtucpiS.cjs');
3
3
 
4
4
  exports.default = require_plugin.tsPlugin;
5
5
  exports.tsPlugin = require_plugin.tsPlugin;
package/dist/index.d.ts CHANGED
@@ -17,6 +17,16 @@ interface TTsPluginOptions {
17
17
  * - `true` — Import `createDataFromAnnotatedType`, create example data on each call.
18
18
  */
19
19
  exampleData?: boolean;
20
+ /**
21
+ * Extension the emitted JS uses for **relative** `.as` imports
22
+ * (`./user` → `./user.as` by default). Bare specifiers (packages, e.g.
23
+ * `some-pkg/models/user.as`) always keep `.as` because they resolve through
24
+ * the package's `exports` map.
25
+ *
26
+ * `.as.mjs` is what `asc db sync` uses to load the compiled models straight
27
+ * from Node. *(default: `'.as'`)*
28
+ */
29
+ moduleExtension?: '.as' | '.as.js' | '.as.mjs';
20
30
  }
21
31
  declare const tsPlugin: (opts?: TTsPluginOptions) => TAtscriptPlugin;
22
32
 
package/dist/index.mjs CHANGED
@@ -1,3 +1,3 @@
1
- import { t as tsPlugin } from "./plugin-DHhdrTs8.mjs";
1
+ import { t as tsPlugin } from "./plugin-ac7ZXMDN.mjs";
2
2
 
3
3
  export { tsPlugin as default, tsPlugin };
@@ -691,6 +691,12 @@ const QUERY_OP_MAP = {
691
691
  "not exists": "$exists"
692
692
  };
693
693
  var JsRenderer = class extends BaseRenderer {
694
+ /**
695
+ * Relative imports get the configured `moduleExtension`; bare specifiers
696
+ * always keep `.as` — they resolve through the package's `exports` map.
697
+ */ transformFromPath(path) {
698
+ return (0, _atscript_core.isBareSpecifier)(path) ? `${path}.as` : `${path}${this.opts?.moduleExtension ?? ".as"}`;
699
+ }
694
700
  /**
695
701
  * Override base `unused` to subtract symbols that the JS output references
696
702
  * transitively through `extends`-resolved parent prop trees. Without this,
@@ -1,6 +1,6 @@
1
1
  import { l as defineAnnotatedType, t as buildJsonSchema } from "./json-schema-DycaD0Rm.mjs";
2
2
  import path from "path";
3
- import { DEFAULT_FORMAT, flattenInterfaceNode, getRelPath, hasNavPropAnnotation, isArray, isBareId, isConst, isGroup, isInterface, isPrimitive, isProp, isQueryLogical, isRef, isStructure } from "@atscript/core";
3
+ import { DEFAULT_FORMAT, flattenInterfaceNode, getRelPath, hasNavPropAnnotation, isArray, isBareId, isBareSpecifier, isConst, isGroup, isInterface, isPrimitive, isProp, isQueryLogical, isRef, isStructure } from "@atscript/core";
4
4
 
5
5
  //#region packages/typescript/src/codegen/code-printer.ts
6
6
  function _define_property$3(obj, key, value) {
@@ -663,6 +663,12 @@ const QUERY_OP_MAP = {
663
663
  "not exists": "$exists"
664
664
  };
665
665
  var JsRenderer = class extends BaseRenderer {
666
+ /**
667
+ * Relative imports get the configured `moduleExtension`; bare specifiers
668
+ * always keep `.as` — they resolve through the package's `exports` map.
669
+ */ transformFromPath(path) {
670
+ return isBareSpecifier(path) ? `${path}.as` : `${path}${this.opts?.moduleExtension ?? ".as"}`;
671
+ }
666
672
  /**
667
673
  * Override base `unused` to subtract symbols that the JS output references
668
674
  * transitively through `extends`-resolved parent prop trees. Without this,
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
- const require_plugin = require('./plugin-Cs9mKJ8h.cjs');
2
+ const require_plugin = require('./plugin-BYtucpiS.cjs');
3
3
  let path = require("path");
4
4
  path = require_plugin.__toESM(path);
5
5
  let _atscript_core = require("@atscript/core");
@@ -1,4 +1,4 @@
1
- import { t as tsPlugin } from "./plugin-DHhdrTs8.mjs";
1
+ import { t as tsPlugin } from "./plugin-ac7ZXMDN.mjs";
2
2
  import path from "path";
3
3
  import { build } from "@atscript/core";
4
4
  import { readFileSync, writeFileSync } from "fs";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atscript/typescript",
3
- "version": "0.1.90",
3
+ "version": "0.1.91",
4
4
  "description": "Atscript: typescript-gen support.",
5
5
  "keywords": [
6
6
  "annotations",
@@ -73,7 +73,7 @@
73
73
  },
74
74
  "peerDependencies": {
75
75
  "@atscript/db": "^0.1.97",
76
- "@atscript/core": "^0.1.90"
76
+ "@atscript/core": "^0.1.91"
77
77
  },
78
78
  "peerDependenciesMeta": {
79
79
  "@atscript/db": {