@arcgis/node-toolkit 6.0.0-next.2 → 6.0.0-next.20

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/env.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Reads the .env file and loads the environment variables.
3
+ *
4
+ * @param searchRoot Set this to `import.meta.dirname`. If no `.env` file is found, will search at `process.cwd()`.
5
+ */
6
+ export declare function readEnvFile(searchRoot: string): void;
package/dist/env.js ADDED
@@ -0,0 +1,10 @@
1
+ import { findPath } from "./file.js";
2
+ function readEnvFile(searchRoot) {
3
+ const envFile = findPath(".env", searchRoot) ?? findPath(".env");
4
+ if (envFile !== void 0) {
5
+ process.loadEnvFile(envFile);
6
+ }
7
+ }
8
+ export {
9
+ readEnvFile
10
+ };
package/dist/glob.d.ts CHANGED
@@ -19,10 +19,3 @@
19
19
  * ```
20
20
  */
21
21
  export declare function gitIgnoreFileToGlobs(filePath: string): string[];
22
- /**
23
- * @public
24
- * @param pattern
25
- * @deprecated Use gitIgnoreFileToGlobs from "@arcgis/node-toolkit/glob"
26
- * instead
27
- */
28
- export declare const gitIgnoreToGlob: (pattern: string) => string;
package/dist/glob.js CHANGED
@@ -1,8 +1,7 @@
1
1
  import { readFileSync } from "node:fs";
2
2
  function gitIgnoreFileToGlobs(filePath) {
3
- return readFileSync(filePath, "utf8").split("\n").filter((line) => line.trim().length > 0 && !line.trim().startsWith("#")).map(gitIgnoreToGlob);
3
+ return readFileSync(filePath, "utf8").split("\n").filter((line) => line.trim().length > 0 && !line.trim().startsWith("#")).map((pattern) => fixAbsoluteSyntax(fixMatchFilesSyntax(pattern.trim())));
4
4
  }
5
- const gitIgnoreToGlob = (pattern) => fixAbsoluteSyntax(fixMatchFilesSyntax(pattern.trim()));
6
5
  function fixAbsoluteSyntax(pattern) {
7
6
  if (pattern.startsWith("/")) {
8
7
  return pattern.slice(1);
@@ -23,6 +22,5 @@ function fixMatchFilesSyntax(pattern) {
23
22
  return pattern.endsWith("/*") ? `${pattern}*` : pattern.endsWith("/") ? `${pattern}**` : `${pattern}/**`;
24
23
  }
25
24
  export {
26
- gitIgnoreFileToGlobs,
27
- gitIgnoreToGlob
25
+ gitIgnoreFileToGlobs
28
26
  };
@@ -0,0 +1,9 @@
1
+ export declare const markdownTextLimit = 65000;
2
+ /**
3
+ * Split markdown to fit into GitHub comment length limit. Splits at best available
4
+ * places: headings (higher levels first), code blocks and details sections, blank lines.
5
+ *
6
+ * Use cases: automated reports in issues, pull request check status comments,
7
+ * reporting public API diff inside a pr comment.
8
+ */
9
+ export declare function splitMarkdown(content: string, limit?: number): string[];
@@ -0,0 +1,103 @@
1
+ const markdownTextLimit = 65e3;
2
+ const boundaryKinds = ["heading", "block", "blank", "line", "text"];
3
+ function splitMarkdown(content, limit = markdownTextLimit) {
4
+ if (!Number.isSafeInteger(limit) || limit < 2) {
5
+ throw new Error("Markdown limit must be an integer of at least 2.");
6
+ }
7
+ const chunks = [];
8
+ let start = 0;
9
+ let blocks = [];
10
+ let prefix = "";
11
+ while (prefix.length + content.length - start > limit) {
12
+ const remaining = content.slice(start);
13
+ const split = getBoundary(remaining, limit - prefix.length, blocks, start === 0 || content[start - 1] === "\n");
14
+ chunks.push(
15
+ prefix + remaining.slice(0, split.index) + closeBlocks(split.blocks, remaining[split.index - 1] === "\n")
16
+ );
17
+ start += split.index;
18
+ blocks = split.blocks;
19
+ prefix = openBlocks(blocks);
20
+ }
21
+ chunks.push(prefix + content.slice(start));
22
+ return chunks;
23
+ }
24
+ function getBoundary(content, limit, initialBlocks, atLineStart) {
25
+ const blocks = [...initialBlocks];
26
+ let best;
27
+ let skipEnd = 0;
28
+ for (const match of content.matchAll(/[^\n]*(?:\n|$)/gu)) {
29
+ const index = match.index;
30
+ if (index > limit) {
31
+ break;
32
+ }
33
+ const line = match[0];
34
+ const end = index + line.length;
35
+ let textStart = Math.max(index, skipEnd);
36
+ if (end <= textStart) {
37
+ continue;
38
+ }
39
+ const aligned = textStart === index && (index > 0 || atLineStart);
40
+ const fence = aligned ? /^ {0,3}(`{3,}|~{3,})([^\r\n]*)/u.exec(line) : null;
41
+ const activeFence = blocks.at(-1)?.fence;
42
+ const heading = aligned && activeFence === void 0 ? /^ {0,3}(#{1,6})\s/u.exec(line) : null;
43
+ const opening = aligned && activeFence === void 0 ? /^[ \t]*<details\b[^>]*>(?:\s*<summary\b[^>]*>[\s\S]*?<\/summary\s*>)?/iu.exec(content.slice(index)) : null;
44
+ const kind = !aligned ? "text" : activeFence !== void 0 ? "line" : opening !== null || fence !== null ? "block" : heading !== null ? "heading" : /^\s*$/u.test(line) ? "blank" : "line";
45
+ consider(textStart, kind, heading?.[1].length);
46
+ if (activeFence !== void 0) {
47
+ if (fence !== null && fence[1].startsWith(activeFence[0]) && fence[1].length >= activeFence.length && fence[2].trim() === "") {
48
+ blocks.pop();
49
+ textStart = end;
50
+ }
51
+ } else if (fence !== null) {
52
+ blocks.push({ opening: line.trimEnd(), closing: fence[1], fence: fence[1] });
53
+ textStart = end;
54
+ } else if (aligned && /^\s*<!--/u.test(line)) {
55
+ const closing = content.indexOf("-->", index);
56
+ textStart = closing === -1 ? content.length : closing + 3;
57
+ } else if (opening !== null) {
58
+ if (/<\/details\s*>/iu.test(line)) {
59
+ textStart = end;
60
+ } else {
61
+ blocks.push({ opening: opening[0], closing: "</details>" });
62
+ textStart = index + opening[0].length;
63
+ }
64
+ } else if (aligned && /^\s*<\/details\s*>/iu.test(line)) {
65
+ blocks.pop();
66
+ textStart = end;
67
+ }
68
+ skipEnd = textStart;
69
+ if (textStart <= end) {
70
+ consider(end, line.endsWith("\n") ? "line" : "text");
71
+ let exact = Math.min(end, limit - closeBlocks(blocks).length);
72
+ if (/[\uD800-\uDBFF]/u.test(content[exact - 1]) && /[\uDC00-\uDFFF]/u.test(content[exact])) {
73
+ exact--;
74
+ }
75
+ if (exact >= textStart) {
76
+ consider(exact, "text");
77
+ }
78
+ }
79
+ }
80
+ if (best === void 0) {
81
+ throw new Error("Markdown limit is too small to split the enclosing blocks.");
82
+ }
83
+ return best;
84
+ function consider(index, kind, headingLevel = 0) {
85
+ if (index <= 0 || index + closeBlocks(blocks, content[index - 1] === "\n").length > limit) {
86
+ return;
87
+ }
88
+ if (best === void 0 || boundaryKinds.indexOf(kind) < boundaryKinds.indexOf(best.kind) || kind === best.kind && (headingLevel < best.headingLevel || headingLevel === best.headingLevel && index > best.index)) {
89
+ best = { index, kind, headingLevel, blocks: [...blocks] };
90
+ }
91
+ }
92
+ }
93
+ function closeBlocks(blocks, endsWithNewline = false) {
94
+ return blocks.length === 0 ? "" : `${endsWithNewline ? "" : "\n"}${blocks.toReversed().map(({ closing }) => closing).join("\n")}
95
+ `;
96
+ }
97
+ function openBlocks(blocks) {
98
+ return blocks.map(({ opening, fence }) => opening + (fence === void 0 ? "\n\n" : "\n")).join("");
99
+ }
100
+ export {
101
+ markdownTextLimit,
102
+ splitMarkdown
103
+ };
@@ -51,7 +51,7 @@ export type PackageJson = {
51
51
  /** @public */
52
52
  "css.customData"?: string[];
53
53
  /** @public */
54
- "customElements"?: string;
54
+ "customElements"?: string[] | string;
55
55
  /** @public */
56
56
  "html.customData"?: string[];
57
57
  /** @public */
package/dist/shell.d.ts CHANGED
@@ -46,24 +46,6 @@ export declare function sh(command: string, options?: Partial<ExecSyncOptionsWit
46
46
  * @param options
47
47
  */
48
48
  export declare function asyncSh(command: string, options?: Partial<ExecOptionsWithStringEncoding>): Promise<string>;
49
- /**
50
- * Synchronously execute a command without shell interpolation and return the output.
51
- *
52
- * This is usually safer than {@link shell!sh} because arguments are passed as
53
- * discrete tokens, which avoids most shell escaping issues and command
54
- * injection pitfalls.
55
- *
56
- * Example:
57
- * `sp("git", ["show", `${baseRef}:pnpm-workspace.yaml`])`
58
- *
59
- * Avoid {@link shell!sp} only when you explicitly need shell features.
60
- * @public
61
- * @deprecated Use {@link shell!collectOutputSync} or {@link shell!runCommandSync} instead.
62
- * @param command
63
- * @param args
64
- * @param options
65
- */
66
- export declare function sp(command: string, args: string[], options?: Partial<SpawnSyncOptionsWithStringEncoding>): string;
67
49
  /**
68
50
  * Synchronously execute a command and stream output to the current process.
69
51
  * Note 1:
package/dist/shell.js CHANGED
@@ -43,26 +43,6 @@ ${output}`;
43
43
  });
44
44
  }
45
45
  }
46
- function sp(command, args, options = {}) {
47
- if (process.platform === "win32" && command === "pnpm" && // Allow explicit shell config including shell:false for environment-specific handling.
48
- !("shell" in options)) {
49
- throw Error(
50
- 'If invoking pnpm on Windows, provide { shell: true } or { shell: process.platform === "win32" } and handle shell escaping.'
51
- );
52
- }
53
- const normalizedOptions = { encoding: "utf8", ...options };
54
- const result = spawnSync(command, args, normalizedOptions);
55
- if (result.error) {
56
- throw result.error;
57
- }
58
- const sep = result.stdout && result.stderr ? "\n" : "";
59
- const output = `${result.stdout ?? ""}${sep}${result.stderr ?? ""}`.trim();
60
- const exitCode = result.status ?? 0;
61
- if (exitCode !== 0) {
62
- throw makeSpawnError(command, args, exitCode, result.signal, output);
63
- }
64
- return output;
65
- }
66
46
  function runCommandSync(command, args, options = {}) {
67
47
  const fixedOptions = fixPnpmUsage(command, options);
68
48
  const { input } = fixedOptions;
@@ -155,6 +135,5 @@ export {
155
135
  collectOutputSync,
156
136
  runCommand,
157
137
  runCommandSync,
158
- sh,
159
- sp
138
+ sh
160
139
  };
@@ -2,7 +2,7 @@ import { mkdir, rm, stat } from "node:fs/promises";
2
2
  import { homedir } from "node:os";
3
3
  import { join } from "node:path";
4
4
  import { findPath, existsAsync } from "../file.js";
5
- import { runCommand } from "../shell.js";
5
+ import { runCommand, collectOutput } from "../shell.js";
6
6
  import { pathToFileURL } from "node:url";
7
7
  let installPromise;
8
8
  function installPlaywright() {
@@ -26,7 +26,20 @@ async function ensureInstalled() {
26
26
  throw new Error("Playwright not found in node_modules. Please install it first.");
27
27
  }
28
28
  const { chromium } = await import(pathToFileURL(join(playwrightCwd, "index.mjs")).href);
29
- if (await existsAsync(chromium.executablePath())) {
29
+ const executablePath = chromium.executablePath();
30
+ const isReady = async () => {
31
+ if (!await existsAsync(executablePath)) {
32
+ return false;
33
+ }
34
+ if (process.platform === "linux" && process.env.CI) {
35
+ const dependencies = await collectOutput("ldd", [executablePath], {
36
+ env: { ...process.env, [`LC_ALL`]: "C" }
37
+ });
38
+ return !dependencies.includes("=> not found");
39
+ }
40
+ return true;
41
+ };
42
+ if (await isReady()) {
30
43
  return;
31
44
  }
32
45
  const home = homedir();
@@ -36,7 +49,7 @@ async function ensureInstalled() {
36
49
  await mkdir(stateDir, { recursive: true });
37
50
  const releaseLock = await acquireLock(lockPath);
38
51
  try {
39
- if (await existsAsync(chromium.executablePath())) {
52
+ if (await isReady()) {
40
53
  return;
41
54
  }
42
55
  const installArgs = [
@@ -1,16 +1,7 @@
1
1
  import type { Plugin } from "vite";
2
- import type dts from "vite-plugin-dts";
3
2
  import { type DependencyManagementOptions } from "./externalizeDependenciesPlugin.ts";
4
3
  /** @public */
5
- export type VitePresetOptions = DependencyManagementOptions & {
6
- /**
7
- * Options for `vite-plugin-dts`
8
- *
9
- * @public
10
- * @deprecated Use https://webgis.esri.com/references/api-extractor/integrations instead
11
- */
12
- dtsOptions?: Parameters<typeof dts>[0] | false;
13
- };
4
+ export type VitePresetOptions = DependencyManagementOptions;
14
5
  /**
15
6
  * Vite preset for all our support packages:
16
7
  * - externalizes all non-dev-dependencies
@@ -18,4 +9,4 @@ export type VitePresetOptions = DependencyManagementOptions & {
18
9
  * @public
19
10
  * @param options
20
11
  */
21
- export declare function vitePresetPlugin({ dtsOptions, externalize, bundleIn, isApplication }?: VitePresetOptions): [Plugin, Plugin, Promise<Plugin> | undefined];
12
+ export declare function vitePresetPlugin({ externalize, bundleIn, isApplication }?: VitePresetOptions): [Plugin, Plugin];
@@ -1,24 +1,13 @@
1
- import { path } from "../path.js";
2
1
  import { externalizeDependencies } from "./externalizeDependenciesPlugin.js";
3
- function shouldSkip(id) {
4
- return id.includes("__test") || id.includes(".e2e.") || id.includes(".spec.") || id.includes(".test.") || id.includes(".stories.");
5
- }
6
2
  const hashlessOutputNames = {
7
3
  assetFileNames: "assets/[name][extname]",
8
4
  chunkFileNames: "chunks/[name].js"
9
5
  };
10
- function vitePresetPlugin({ dtsOptions = {}, externalize, bundleIn, isApplication } = {
11
- externalize: [],
12
- dtsOptions: {}
13
- }) {
14
- const dist = `${path.resolve("dist")}/`;
15
- const distSrc = `${dist}src/`;
16
- let command = void 0;
6
+ function vitePresetPlugin({ externalize, bundleIn, isApplication } = { externalize: [] }) {
17
7
  return [
18
8
  {
19
9
  name: "vite-preset-config",
20
10
  config(config, env) {
21
- command = env.command;
22
11
  const { rollupOptions, ssr, target } = config.build ?? {};
23
12
  const isBrowserApplication = isApplication && !ssr && !env.isSsrBuild;
24
13
  const output = rollupOptions?.output;
@@ -40,44 +29,7 @@ function vitePresetPlugin({ dtsOptions = {}, externalize, bundleIn, isApplicatio
40
29
  externalize,
41
30
  bundleIn,
42
31
  isApplication
43
- }),
44
- // This dependency pulls in many others. Since components-build-utils has a
45
- // single entry point, we load a large module tree needlessly. To avoid,
46
- // load the plugin on demand.
47
- dtsOptions === false ? void 0 : import("vite-plugin-dts").then(
48
- ({ default: dts }) => dts({
49
- logLevel: "warn",
50
- ...dtsOptions,
51
- compilerOptions: {
52
- rootDir: ".",
53
- ...dtsOptions.compilerOptions
54
- },
55
- /**
56
- * Do not emit any .d.ts files for files outside the dist directory
57
- * (i.e vite.config.ts, storybook stories and etc)
58
- * This also applies for references to node_modules/.../components.d.ts files in
59
- * tsconfig.json - these must be included in TypeScript program to provide
60
- * types, but should not be re-emitted during build.
61
- */
62
- beforeWriteFile: async (filePath, content) => {
63
- if (filePath.startsWith(distSrc) && !shouldSkip(filePath)) {
64
- const filePathRelativeToDist = `${dist}${filePath.slice(distSrc.length)}`;
65
- return dtsOptions?.beforeWriteFile ? await dtsOptions.beforeWriteFile(filePathRelativeToDist, content) : { filePath: filePathRelativeToDist, content };
66
- } else {
67
- return false;
68
- }
69
- },
70
- afterDiagnostic(diagnostics) {
71
- const hasErrors = diagnostics.length > 0;
72
- const isBuilding = command === "build";
73
- const stopBuild = hasErrors && isBuilding;
74
- if (stopBuild) {
75
- throw new Error("TypeScript errors reported. See error messages above");
76
- }
77
- return dtsOptions?.afterDiagnostic?.(diagnostics);
78
- }
79
- })
80
- )
32
+ })
81
33
  ];
82
34
  }
83
35
  export {
package/package.json CHANGED
@@ -1,12 +1,14 @@
1
1
  {
2
2
  "name": "@arcgis/node-toolkit",
3
- "version": "6.0.0-next.2",
3
+ "version": "6.0.0-next.20",
4
4
  "description": "Collection of common internal build-time patterns and utilities for ArcGIS Maps SDK for JavaScript components.",
5
5
  "homepage": "https://developers.arcgis.com/javascript/latest/",
6
6
  "type": "module",
7
7
  "exports": {
8
8
  "./codeowners": "./dist/codeowners.js",
9
+ "./env": "./dist/env.js",
9
10
  "./file": "./dist/file.js",
11
+ "./markdown": "./dist/markdown.js",
10
12
  "./shell": "./dist/shell.js",
11
13
  "./glob": "./dist/glob.js",
12
14
  "./path": "./dist/path.js",
@@ -27,7 +29,6 @@
27
29
  "picomatch": "^4.0.4",
28
30
  "tslib": "^2.8.1",
29
31
  "typescript": "~6.0.3",
30
- "vite": "^7.3.2",
31
- "vite-plugin-dts": "^4.5.4"
32
+ "vite": "^7.3.2"
32
33
  }
33
34
  }