@zntc/core 0.1.4 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -37,7 +37,7 @@ bun add -D browserslist core-js core-js-compat lightningcss
37
37
  bunx zntc src/index.ts --outfile out.js
38
38
 
39
39
  # Bundle (multi-entry)
40
- bunx zntc --bundle src/index.ts --outfile dist/bundle.js --format=esm --target=node
40
+ bunx zntc --bundle src/index.ts --outfile dist/bundle.js --format=esm --platform=node
41
41
  ```
42
42
 
43
43
  See `bunx zntc --help` for the full list of options.
package/bin/cli-flags.mjs CHANGED
@@ -239,6 +239,7 @@ export const FLAG_REGISTRY = [
239
239
  // ─── kind=key-value — `--key:K=V` → opts[target][K]=V ───
240
240
  { kind: 'key-value', flag: '--define', target: 'define' },
241
241
  { kind: 'key-value', flag: '--alias', target: 'alias' },
242
+ { kind: 'key-value', flag: '--external-alias', target: 'externalAlias' },
242
243
  // Fallback resolution — 해석 실패 시에만 적용 (webpack resolve.fallback /
243
244
  // Metro extraNodeModules 호환). `--fallback:crypto=crypto-browserify`.
244
245
  // 값 "false" → 빈-모듈 강제 + specifier 제약은 normalizeFallback 참조.
package/bin/zntc.mjs CHANGED
@@ -17,7 +17,7 @@ import {
17
17
  unlinkSync,
18
18
  writeFileSync,
19
19
  } from 'node:fs';
20
- import { resolve, dirname, basename, extname, join, sep } from 'node:path';
20
+ import { resolve, dirname, basename, extname, join, sep, relative, isAbsolute } from 'node:path';
21
21
  import { createServer } from 'node:http';
22
22
  import { createServer as createHttpsServer } from 'node:https';
23
23
  import { createRequire } from 'node:module';
@@ -296,6 +296,7 @@ function parseArgs(argv) {
296
296
  packagesExternal: false,
297
297
  define: {},
298
298
  alias: {},
299
+ externalAlias: {},
299
300
  banner: undefined,
300
301
  footer: undefined,
301
302
  globalName: undefined,
@@ -1228,12 +1229,17 @@ async function runTranspile(opts) {
1228
1229
 
1229
1230
  if (opts.outfile || opts.outdir) {
1230
1231
  const name = basename(opts.entryPoints[0]).replace(/\.[^.]+$/, '.js');
1232
+ // 맵이 놓일 자리 — sources 를 그 자리 기준으로 적어야 브라우저가 원본을 찾는다.
1233
+ const outPath = opts.outfile ? resolve(opts.outfile) : join(resolve(opts.outdir), name);
1234
+ const { code, map } = finishTranspileSourcemap(result, outPath, opts.sourcemapMode);
1231
1235
  // transpile result.code / result.map 은 string — writeOutputFiles 는 contents
1232
1236
  // (Uint8Array) 를 받으므로 `Buffer.from` 으로 한 번 변환. 같은 메모리 backing 의
1233
1237
  // utf-8 byte view 라 추가 copy 없음.
1234
- const outputFiles = [{ path: name, contents: Buffer.from(result.code) }];
1235
- if (opts.outfile && result.map) {
1236
- outputFiles.push({ path: name + '.map', contents: Buffer.from(result.map) });
1238
+ const outputFiles = [{ path: name, contents: Buffer.from(code) }];
1239
+ // outdir 로 낼 때도 맵을 함께 낸다 — 예전엔 outfile 때만 내서
1240
+ // `--outdir --sourcemap` 조용히 없이 끝났다.
1241
+ if (map) {
1242
+ outputFiles.push({ path: name + '.map', contents: Buffer.from(map) });
1237
1243
  }
1238
1244
  writeOutputFiles(outputFiles, opts.outfile, opts.outdir, opts.entryPoints, opts.allowOverwrite);
1239
1245
  } else {
@@ -1245,6 +1251,52 @@ async function runTranspile(opts) {
1245
1251
  }
1246
1252
  }
1247
1253
 
1254
+ /**
1255
+ * transpile 결과의 소스맵을 출력 자리에 맞게 마무리한다.
1256
+ *
1257
+ * 셋 다 CLI 만 아는 것이라 여기서 한다 — 라이브러리 호출자는 출력 경로를
1258
+ * 스스로 정하므로 그쪽이 맡는다.
1259
+ *
1260
+ * 1. `sources` 를 **맵이 놓일 자리 기준**으로 고친다. 엔진은 넘겨받은 파일
1261
+ * 이름(대개 CWD 기준)을 그대로 적어서, `-o dist/x.js` 로 내면 브라우저가
1262
+ * `dist/src/x.ts` 를 찾다 못 찾는다. tsc·esbuild 도 출력 기준으로 적는다.
1263
+ * 2. `file` 에 생성 파일 이름을 채운다 — 소스맵 v3 의 `file` 은 *생성된* 파일이다.
1264
+ * 3. 모드대로 마무리한다. linked(기본)는 `//# sourceMappingURL=` 주석을 붙이고,
1265
+ * external 은 맵만 내고 주석은 안 붙이며, inline 은 맵을 파일로 내지 않고
1266
+ * data URL 로 코드에 심는다. 예전에는 어느 모드든 주석이 안 붙어, 맵을 내고도
1267
+ * 브라우저가 찾지 못했다(inline 인데 .map 파일이 따로 나오기도 했다).
1268
+ */
1269
+ function finishTranspileSourcemap(result, outPath, mode) {
1270
+ if (!result.map) return { code: result.code, map: null };
1271
+ let json;
1272
+ try {
1273
+ json = JSON.parse(result.map);
1274
+ } catch {
1275
+ return { code: result.code, map: result.map }; // 못 읽으면 손대지 않는다
1276
+ }
1277
+ json.file = basename(outPath);
1278
+ const outDirAbs = dirname(outPath);
1279
+ json.sources = (json.sources ?? []).map((src) => {
1280
+ if (!src || src.startsWith('data:')) return src;
1281
+ const abs = isAbsolute(src) ? src : resolve(src);
1282
+ const rel = relative(outDirAbs, abs).split(sep).join('/');
1283
+ return rel.startsWith('.') ? rel : './' + rel;
1284
+ });
1285
+ const text = JSON.stringify(json);
1286
+
1287
+ if (mode === 'inline') {
1288
+ const url = 'data:application/json;base64,' + Buffer.from(text).toString('base64');
1289
+ return { code: appendSourceMappingURL(result.code, url), map: null };
1290
+ }
1291
+ if (mode === 'external') return { code: result.code, map: text };
1292
+ return { code: appendSourceMappingURL(result.code, basename(outPath) + '.map'), map: text };
1293
+ }
1294
+
1295
+ function appendSourceMappingURL(code, url) {
1296
+ if (code.includes('//# sourceMappingURL=')) return code;
1297
+ return code.replace(/\n*$/, '\n') + '//# sourceMappingURL=' + url + '\n';
1298
+ }
1299
+
1248
1300
  // ─── Bundle 모드 ───
1249
1301
 
1250
1302
  /**
@@ -1477,7 +1529,7 @@ function mergeConfigIntoOpts(opts, config) {
1477
1529
  }
1478
1530
  }
1479
1531
 
1480
- for (const key of ['define', 'alias', 'loader', 'globals', 'fallback']) {
1532
+ for (const key of ['define', 'alias', 'externalAlias', 'loader', 'globals', 'fallback']) {
1481
1533
  if (config[key] && typeof config[key] === 'object') {
1482
1534
  opts[key] = { ...config[key], ...opts[key] };
1483
1535
  }
@@ -1561,6 +1613,9 @@ async function buildBundleOptions(opts, config, { filterCallerPreWarmCss = false
1561
1613
  packagesExternal: opts.packagesExternal,
1562
1614
  // `--alias:K=V` 플래그 (webpack/rollup 스타일) — JS 옵션이 tsconfig paths 보다 우선 적용됨.
1563
1615
  alias: Object.keys(opts.alias).length > 0 ? opts.alias : undefined,
1616
+ // #4616 external 지정자를 다른 이름으로 방출 (rollup output.paths 대응).
1617
+ externalAlias:
1618
+ Object.keys(opts.externalAlias ?? {}).length > 0 ? opts.externalAlias : undefined,
1564
1619
  define: Object.keys(opts.define).length > 0 ? opts.define : undefined,
1565
1620
  loader: Object.keys(opts.loader).length > 0 ? opts.loader : undefined,
1566
1621
  minify: opts.minify,
@@ -625,6 +625,16 @@ interface BuildOptionsCommon {
625
625
  find: string | RegExp;
626
626
  replacement: string;
627
627
  }>;
628
+ /**
629
+ * external 로 남는 지정자를 **다른 이름으로 방출** (rollup `output.paths` /
630
+ * webpack object-form `externals` 대응).
631
+ *
632
+ * `alias` 와 달리 **해석에는 관여하지 않는다** — 이미 external 로 확정된 지정자를
633
+ * 출력에 쓸 때만 이름을 바꾼다. 브라우저용 shim 을 번들하지 않고 이름만 갈아끼울 때 쓴다.
634
+ *
635
+ * @example { crypto: 'crypto-browserify' } // import ... from "crypto-browserify"
636
+ */
637
+ externalAlias?: Record<string, string>;
628
638
  /** alias 의 prefix matching 을 끄는 from 목록 — exact 매칭만 허용.
629
639
  *
630
640
  * `alias` object form 의 기본 동작은 esbuild 처럼 정확/접두사 둘 다 매칭이라
@@ -625,6 +625,16 @@ interface BuildOptionsCommon {
625
625
  find: string | RegExp;
626
626
  replacement: string;
627
627
  }>;
628
+ /**
629
+ * external 로 남는 지정자를 **다른 이름으로 방출** (rollup `output.paths` /
630
+ * webpack object-form `externals` 대응).
631
+ *
632
+ * `alias` 와 달리 **해석에는 관여하지 않는다** — 이미 external 로 확정된 지정자를
633
+ * 출력에 쓸 때만 이름을 바꾼다. 브라우저용 shim 을 번들하지 않고 이름만 갈아끼울 때 쓴다.
634
+ *
635
+ * @example { crypto: 'crypto-browserify' } // import ... from "crypto-browserify"
636
+ */
637
+ externalAlias?: Record<string, string>;
628
638
  /** alias 의 prefix matching 을 끄는 from 목록 — exact 매칭만 허용.
629
639
  *
630
640
  * `alias` object form 의 기본 동작은 esbuild 처럼 정확/접두사 둘 다 매칭이라
package/dist/index.cjs CHANGED
@@ -61,7 +61,7 @@ function validateTsConfigRaw(raw) {
61
61
  }
62
62
  function buildOptionsJson(opts={},unsupportedOverride) {
63
63
  const payload = {};
64
- if (opts.target)payload.target = opts.target;
64
+ if (opts.target && ES_TARGET_BITS[opts.target] !== undefined)payload.target = opts.target;
65
65
  if (unsupportedOverride !== undefined && unsupportedOverride !== 0)payload.unsupported = unsupportedOverride;
66
66
  if (opts.flow)payload.flow = true;
67
67
  if (opts.jsxInJs)payload.jsxInJs = true;
@@ -555,7 +555,7 @@ function warnUnknownKeys(config,known,options={}) {
555
555
  }
556
556
  return result;
557
557
  }
558
- const KNOWN_CONFIG_KEYS = ["entryPoints", "output", "outdir", "outfile", "outbase", "format", "platform", "target", "rnVersion", "diskCache", "cacheDir", "browserslist", "runtimePolyfills", "coreJs", "jsx", "jsxDev", "jsxFactory", "jsxFragment", "jsxImportSource", "jsxInJs", "jsxSideEffects", "minify", "minifyWhitespace", "minifyIdentifiers", "minifySyntax", "sourcemap", "sourcemapMode", "sourcemapDebugIds", "sourcesContent", "sourceRoot", "external", "alias", "aliasExact", "define", "server", "loader", "conditions", "nodePaths", "moduleSpecifierMap", "resolveExtensions", "mainFields", "packagesExternal", "preserveSymlinks", "resolveSymlinkSiblings", "disableHierarchicalLookup", "splitting", "outputExports", "preserveModules", "preserveModulesRoot", "inlineDynamicImports", "manualChunks", "minChunkSize", "metafile", "treeShaking", "shimMissingExports", "keepNames", "drop", "dropConsole", "dropDebugger", "dropLabels", "banner", "footer", "intro", "outro", "inject", "pure", "legalComments", "entryNames", "chunkNames", "assetNames", "assetInlineLimit", "cssNames", "experimentalDecorators", "emitDecoratorMetadata", "useDefineForClassFields", "verbatimModuleSyntax", "tsconfigPath", "tsconfigRaw", "globalName", "globals", "publicPath", "charsetUtf8", "asciiOnly", "quotes", "compiler", "mf", "flow", "plugins", "logLevel", "logLimit", "lineLimit", "profile", "profileFormat", "profileLevel", "tokenizeFormat", "stopAfter", "ignoreAnnotations", "watchDelay", "jobs", "codegenTransform", "lazyCompilation", "lazyForceParse", "preserveSafePlugins", "extends", "root", "projectRoot", "entry", "dev", "outDir", "bundler", "resolver", "transformer", "serializer", "symbolicator", "watchFolders"];
558
+ const KNOWN_CONFIG_KEYS = ["entryPoints", "output", "outdir", "outfile", "outbase", "format", "platform", "target", "rnVersion", "diskCache", "cacheDir", "browserslist", "runtimePolyfills", "coreJs", "jsx", "jsxDev", "jsxFactory", "jsxFragment", "jsxImportSource", "jsxInJs", "jsxSideEffects", "minify", "minifyWhitespace", "minifyIdentifiers", "minifySyntax", "sourcemap", "sourcemapMode", "sourcemapDebugIds", "sourcesContent", "sourceRoot", "external", "alias", "externalAlias", "aliasExact", "define", "server", "loader", "conditions", "nodePaths", "moduleSpecifierMap", "resolveExtensions", "mainFields", "packagesExternal", "preserveSymlinks", "resolveSymlinkSiblings", "disableHierarchicalLookup", "splitting", "outputExports", "preserveModules", "preserveModulesRoot", "inlineDynamicImports", "manualChunks", "minChunkSize", "metafile", "treeShaking", "shimMissingExports", "keepNames", "drop", "dropConsole", "dropDebugger", "dropLabels", "banner", "footer", "intro", "outro", "inject", "pure", "legalComments", "entryNames", "chunkNames", "assetNames", "assetInlineLimit", "cssNames", "experimentalDecorators", "emitDecoratorMetadata", "useDefineForClassFields", "verbatimModuleSyntax", "tsconfigPath", "tsconfigRaw", "globalName", "globals", "publicPath", "charsetUtf8", "asciiOnly", "quotes", "compiler", "mf", "flow", "plugins", "logLevel", "logLimit", "lineLimit", "profile", "profileFormat", "profileLevel", "tokenizeFormat", "stopAfter", "ignoreAnnotations", "watchDelay", "jobs", "codegenTransform", "lazyCompilation", "lazyForceParse", "preserveSafePlugins", "extends", "root", "projectRoot", "entry", "dev", "outDir", "bundler", "resolver", "transformer", "serializer", "symbolicator", "watchFolders"];
559
559
  //#endregion
560
560
  //#region workspace.ts
561
561
  var existsSync$1 = require("node:fs").existsSync;
@@ -776,7 +776,10 @@ function resolveUnsupported(options) {
776
776
  }
777
777
  return browserslistToUnsupported(bl(options.browserslist));
778
778
  }
779
- return options.target ? ES_TARGET_BITS[options.target] ?? 0 : 0;
779
+ if (!options.target)return 0;
780
+ const esBits = ES_TARGET_BITS[options.target];
781
+ if (esBits !== undefined)return esBits;
782
+ return ensureNative().targetToUnsupported(options.target);
780
783
  }
781
784
  var TsconfigCache = class {
782
785
  _handle;
@@ -1220,6 +1223,9 @@ function prepareNapiOptions(options) {
1220
1223
  delete napiOptions.browserslist;
1221
1224
  }
1222
1225
  if (options.target && !isEsTarget(options.target)) {
1226
+ if (napiOptions.unsupported === undefined) {
1227
+ napiOptions.unsupported = ensureNative().targetToUnsupported(options.target);
1228
+ }
1223
1229
  delete napiOptions.target;
1224
1230
  }
1225
1231
  delete napiOptions.compiler;
package/dist/index.js CHANGED
@@ -1240,7 +1240,7 @@ function validateTsConfigRaw(raw) {
1240
1240
  }
1241
1241
  function buildOptionsJson(opts = {}, unsupportedOverride) {
1242
1242
  const payload = {};
1243
- if (opts.target)
1243
+ if (opts.target && ES_TARGET_BITS[opts.target] !== undefined)
1244
1244
  payload.target = opts.target;
1245
1245
  if (unsupportedOverride !== undefined && unsupportedOverride !== 0)
1246
1246
  payload.unsupported = unsupportedOverride;
@@ -2244,6 +2244,7 @@ var KNOWN_CONFIG_KEYS = [
2244
2244
  "sourceRoot",
2245
2245
  "external",
2246
2246
  "alias",
2247
+ "externalAlias",
2247
2248
  "aliasExact",
2248
2249
  "define",
2249
2250
  "server",
@@ -2574,7 +2575,12 @@ function resolveUnsupported(options) {
2574
2575
  }
2575
2576
  return browserslistToUnsupported(bl(options.browserslist));
2576
2577
  }
2577
- return options.target ? ES_TARGET_BITS[options.target] ?? 0 : 0;
2578
+ if (!options.target)
2579
+ return 0;
2580
+ const esBits = ES_TARGET_BITS[options.target];
2581
+ if (esBits !== undefined)
2582
+ return esBits;
2583
+ return ensureNative().targetToUnsupported(options.target);
2578
2584
  }
2579
2585
 
2580
2586
  class TsconfigCache {
@@ -3183,6 +3189,9 @@ function prepareNapiOptions(options) {
3183
3189
  delete napiOptions.browserslist;
3184
3190
  }
3185
3191
  if (options.target && !isEsTarget(options.target)) {
3192
+ if (napiOptions.unsupported === undefined) {
3193
+ napiOptions.unsupported = ensureNative().targetToUnsupported(options.target);
3194
+ }
3186
3195
  delete napiOptions.target;
3187
3196
  }
3188
3197
  delete napiOptions.compiler;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zntc/core",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "description": "ZNTC native transpiler & compiler binding",
5
5
  "keywords": [
6
6
  "bundler",
@@ -76,15 +76,15 @@
76
76
  "@zntc/test-helpers": "0.0.0"
77
77
  },
78
78
  "optionalDependencies": {
79
- "@zntc/core-darwin-arm64": "0.1.4",
80
- "@zntc/core-darwin-x64": "0.1.4",
81
- "@zntc/core-linux-arm64-gnu": "0.1.4",
82
- "@zntc/core-linux-arm64-musl": "0.1.4",
83
- "@zntc/core-linux-x64-gnu": "0.1.4",
84
- "@zntc/core-linux-x64-musl": "0.1.4",
85
- "@zntc/core-win32-arm64-msvc": "0.1.4",
86
- "@zntc/core-win32-ia32-msvc": "0.1.4",
87
- "@zntc/core-win32-x64-msvc": "0.1.4",
79
+ "@zntc/core-darwin-arm64": "0.1.6",
80
+ "@zntc/core-darwin-x64": "0.1.6",
81
+ "@zntc/core-linux-arm64-gnu": "0.1.6",
82
+ "@zntc/core-linux-arm64-musl": "0.1.6",
83
+ "@zntc/core-linux-x64-gnu": "0.1.6",
84
+ "@zntc/core-linux-x64-musl": "0.1.6",
85
+ "@zntc/core-win32-arm64-msvc": "0.1.6",
86
+ "@zntc/core-win32-ia32-msvc": "0.1.6",
87
+ "@zntc/core-win32-x64-msvc": "0.1.6",
88
88
  "browserslist": "^4.24.0",
89
89
  "core-js": "^3.49.0",
90
90
  "core-js-compat": "^3.49.0",