@reliverse/dler 1.7.21 → 1.7.23

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 (35) hide show
  1. package/bin/app/agg/impl.js +1 -1
  2. package/bin/app/cmds.d.ts +1 -1
  3. package/bin/app/cmds.js +1 -1
  4. package/bin/app/inject/cmd.d.ts +0 -24
  5. package/bin/app/inject/cmd.js +0 -47
  6. package/bin/app/{spell → magic}/cmd.d.ts +2 -0
  7. package/bin/app/magic/cmd.js +101 -0
  8. package/bin/app/pub/impl.js +4 -2
  9. package/bin/libs/cfg/cfg-mod.d.ts +24 -195
  10. package/bin/libs/cfg/cfg-mod.js +71 -66
  11. package/bin/libs/cfg/constants.d.ts +68 -0
  12. package/bin/libs/cfg/constants.js +60 -0
  13. package/bin/libs/cfg/rse/rse-impl/rse-create.js +1 -1
  14. package/bin/libs/cfg/rse/rse-impl/rse-define.d.ts +11 -11
  15. package/bin/libs/cfg/rse/rse-mod.d.ts +1 -1
  16. package/bin/libs/cfg/rse/rse-mod.js +1 -1
  17. package/bin/libs/sdk/sdk-impl/cmds/inject/inject-impl-mod.d.ts +63 -0
  18. package/bin/libs/sdk/sdk-impl/cmds/inject/inject-impl-mod.js +237 -0
  19. package/bin/libs/sdk/sdk-impl/config/info.js +1 -3
  20. package/bin/libs/sdk/sdk-impl/magic/apply.d.ts +63 -0
  21. package/bin/libs/sdk/sdk-impl/{spell/applyMagicSpells.js → magic/apply.js} +223 -70
  22. package/bin/libs/sdk/sdk-impl/{spell → magic}/spells.d.ts +16 -1
  23. package/bin/libs/sdk/sdk-impl/{spell → magic}/spells.js +41 -1
  24. package/bin/libs/sdk/sdk-impl/rules/reliverse/missing-deps/deps-types.d.ts +1 -1
  25. package/bin/libs/sdk/sdk-mod.d.ts +93 -42
  26. package/bin/libs/sdk/sdk-mod.js +119 -27
  27. package/package.json +2 -2
  28. package/bin/app/inject/impl.d.ts +0 -5
  29. package/bin/app/inject/impl.js +0 -159
  30. package/bin/app/spell/cmd.js +0 -47
  31. package/bin/libs/sdk/sdk-impl/spell/applyMagicSpells.d.ts +0 -38
  32. /package/bin/app/{spell → magic}/old.d.ts +0 -0
  33. /package/bin/app/{spell → magic}/old.js +0 -0
  34. /package/bin/libs/cfg/rse/rse-impl/{rse-inject.d.ts → rse-comments.d.ts} +0 -0
  35. /package/bin/libs/cfg/rse/rse-impl/{rse-inject.js → rse-comments.js} +0 -0
@@ -0,0 +1,68 @@
1
+ import type { DlerConfig } from "./types";
2
+ /**
3
+ * Default configuration for the build and publish logic.
4
+ */
5
+ export declare const DEFAULT_CONFIG_DLER: DlerConfig;
6
+ export declare const defineConfigDler: (userConfig?: Partial<DlerConfig>) => {
7
+ bumpDisable: boolean;
8
+ bumpFilter: string[];
9
+ bumpMode: import("./types").BumpMode;
10
+ bumpSet: string;
11
+ commonPubPause: boolean;
12
+ commonPubRegistry: "jsr" | "npm" | "npm-jsr";
13
+ commonVerbose: boolean;
14
+ coreDeclarations: boolean;
15
+ coreEntryFile: string;
16
+ coreEntrySrcDir: string;
17
+ coreBuildOutDir: string;
18
+ coreIsCLI: {
19
+ enabled: boolean;
20
+ scripts: Record<string, string>;
21
+ };
22
+ coreDescription: string;
23
+ distJsrAllowDirty: boolean;
24
+ distJsrBuilder: import("./types").BundlerName;
25
+ distJsrDirName: string;
26
+ distJsrDryRun: boolean;
27
+ distJsrFailOnWarn: boolean;
28
+ distJsrGenTsconfig: boolean;
29
+ distJsrOutFilesExt: import("./types").NpmOutExt;
30
+ distJsrSlowTypes: boolean;
31
+ distNpmBuilder: import("./types").BundlerName;
32
+ distNpmDirName: string;
33
+ distNpmOutFilesExt: import("./types").NpmOutExt;
34
+ libsActMode: "libs-only" | "main-and-libs" | "main-project-only";
35
+ libsDirDist: string;
36
+ libsDirSrc: string;
37
+ libsList: Record<string, import("./types").LibConfig>;
38
+ logsFileName: string;
39
+ logsFreshFile: boolean;
40
+ filterDepsPatterns: {
41
+ global: string[];
42
+ "dist-npm": string[];
43
+ "dist-jsr": string[];
44
+ "dist-libs": Record<string, {
45
+ npm: string[];
46
+ jsr: string[];
47
+ }>;
48
+ };
49
+ transpileFailOnWarn: boolean;
50
+ transpileEsbuild: import("./types").Esbuild;
51
+ transpileFormat: import("./types").transpileFormat;
52
+ transpileMinify: boolean;
53
+ transpilePublicPath: string;
54
+ transpileSourcemap: import("./types").Sourcemap;
55
+ transpileSplitting: boolean;
56
+ transpileStub: boolean;
57
+ transpileTarget: import("./types").transpileTarget;
58
+ transpileWatch: boolean;
59
+ publishArtifacts?: {
60
+ global: string[];
61
+ "dist-jsr": string[];
62
+ "dist-npm": string[];
63
+ "dist-libs": Record<string, {
64
+ jsr: string[];
65
+ npm: string[];
66
+ }>;
67
+ };
68
+ };
@@ -0,0 +1,60 @@
1
+ export const DEFAULT_CONFIG_DLER = {
2
+ bumpDisable: false,
3
+ bumpFilter: ["package.json", ".config/rse.ts"],
4
+ bumpMode: "patch",
5
+ bumpSet: "",
6
+ commonPubPause: true,
7
+ commonPubRegistry: "npm",
8
+ commonVerbose: false,
9
+ coreDeclarations: true,
10
+ coreDescription: "",
11
+ coreEntryFile: "mod.ts",
12
+ coreEntrySrcDir: "src",
13
+ coreBuildOutDir: "bin",
14
+ coreIsCLI: { enabled: false, scripts: {} },
15
+ distJsrAllowDirty: true,
16
+ distJsrBuilder: "jsr",
17
+ distJsrDirName: "dist-jsr",
18
+ distJsrDryRun: false,
19
+ distJsrFailOnWarn: false,
20
+ distJsrGenTsconfig: false,
21
+ distJsrOutFilesExt: "ts",
22
+ distJsrSlowTypes: true,
23
+ distNpmBuilder: "mkdist",
24
+ distNpmDirName: "dist-npm",
25
+ distNpmOutFilesExt: "js",
26
+ libsActMode: "main-project-only",
27
+ libsDirDist: "dist-libs",
28
+ libsDirSrc: "src/libs",
29
+ libsList: {},
30
+ logsFileName: ".logs/relinka.log",
31
+ logsFreshFile: true,
32
+ // Dependency filtering
33
+ filterDepsPatterns: {
34
+ global: ["@types", "biome", "eslint", "knip", "prettier", "typescript", "@reliverse/dler"],
35
+ "dist-npm": [],
36
+ "dist-jsr": [],
37
+ "dist-libs": {}
38
+ },
39
+ // Build setup
40
+ transpileFailOnWarn: false,
41
+ transpileEsbuild: "es2023",
42
+ transpileFormat: "esm",
43
+ transpileMinify: true,
44
+ transpilePublicPath: "/",
45
+ transpileSourcemap: "none",
46
+ transpileSplitting: false,
47
+ transpileStub: false,
48
+ transpileTarget: "node",
49
+ transpileWatch: false,
50
+ // Publish artifacts configuration
51
+ publishArtifacts: {
52
+ global: ["package.json", "README.md", "LICENSE"],
53
+ "dist-jsr": [],
54
+ "dist-npm": [],
55
+ "dist-libs": {}
56
+ }
57
+ };
58
+ export const defineConfigDler = (userConfig = {}) => {
59
+ return { ...DEFAULT_CONFIG_DLER, ...userConfig };
60
+ };
@@ -5,12 +5,12 @@ import { confirmPrompt } from "@reliverse/rempts";
5
5
  import { Value } from "@sinclair/typebox/value";
6
6
  import { execaCommand } from "execa";
7
7
  import { addDevDependency } from "nypm";
8
+ import { injectSectionComments } from "./rse-comments.js";
8
9
  import { cliDomainDocs } from "./rse-consts.js";
9
10
  import { UNKNOWN_VALUE, rseName, DEFAULT_DOMAIN, RSE_SCHEMA_DEV } from "./rse-consts.js";
10
11
  import { generateDefaultRulesForProject, getDefaultRseConfig } from "./rse-def-utils.js";
11
12
  import { DEFAULT_CONFIG_RSE } from "./rse-default.js";
12
13
  import { getPackageJson, detectFeatures } from "./rse-detect.js";
13
- import { injectSectionComments } from "./rse-inject.js";
14
14
  import { getRseConfigPath } from "./rse-path.js";
15
15
  import { readRseConfig } from "./rse-read.js";
16
16
  import { rseSchema } from "./rse-schema.js";
@@ -11,10 +11,10 @@ export declare const defineConfigRse: (userConfig?: Partial<RseConfig>) => {
11
11
  projectGitService?: "none" | "github" | "gitlab" | "bitbucket" | undefined;
12
12
  projectDeployService?: "none" | "vercel" | "netlify" | "railway" | "deno" | undefined;
13
13
  projectPackageManager?: "npm" | "bun" | "pnpm" | "yarn" | undefined;
14
- projectState?: "created" | "creating" | undefined;
14
+ projectState?: "creating" | "created" | undefined;
15
15
  projectCategory?: "browser" | "cli" | "unknown" | "website" | "vscode" | "library" | "mobile" | undefined;
16
16
  projectSubcategory?: "unknown" | "e-commerce" | "tool" | undefined;
17
- projectFramework?: "vue" | "npm-jsr" | "rempts" | "unknown" | "vscode" | "nextjs" | "vite" | "svelte" | "remix" | "astro" | "nuxt" | "solid" | "qwik" | "wxt" | "lynx" | "react-native" | "expo" | "capacitor" | "ionic" | "electron" | "tauri" | "neutralino" | "citty" | "commander" | "cac" | "meow" | "yargs" | "webextension" | "browser-extension" | undefined;
17
+ projectFramework?: "npm-jsr" | "unknown" | "vscode" | "nextjs" | "vite" | "svelte" | "remix" | "astro" | "nuxt" | "solid" | "qwik" | "vue" | "wxt" | "lynx" | "react-native" | "expo" | "capacitor" | "ionic" | "electron" | "tauri" | "neutralino" | "rempts" | "citty" | "commander" | "cac" | "meow" | "yargs" | "webextension" | "browser-extension" | undefined;
18
18
  projectTemplate?: "unknown" | "blefnk/relivator-nextjs-template" | "blefnk/relivator-docker-template" | "blefnk/next-react-ts-src-minimal" | "blefnk/all-in-one-nextjs-template" | "blefnk/create-t3-app" | "blefnk/create-next-app" | "blefnk/astro-starlight-template" | "blefnk/versator-nextjs-template" | "blefnk/relivator-lynxjs-template" | "blefnk/relivator-react-native-template" | "reliverse/template-browser-extension" | "microsoft/vscode-extension-samples" | "microsoft/vscode-extension-template" | "rsetarter-template" | "blefnk/deno-cli-tutorial" | undefined;
19
19
  projectTemplateDate?: string | undefined;
20
20
  features?: {
@@ -41,12 +41,12 @@ export declare const defineConfigRse: (userConfig?: Partial<RseConfig>) => {
41
41
  testing?: "bun" | "unknown" | "vitest" | "jest" | "playwright" | "cypress" | undefined;
42
42
  stateManagement?: "unknown" | "zustand" | "jotai" | "redux-toolkit" | undefined;
43
43
  formManagement?: "unknown" | "react-hook-form" | "formik" | undefined;
44
- styling?: "sass" | "unknown" | "tailwind" | "styled-components" | "css-modules" | undefined;
44
+ styling?: "unknown" | "tailwind" | "styled-components" | "css-modules" | "sass" | undefined;
45
45
  uiComponents?: "unknown" | "shadcn-ui" | "chakra-ui" | "material-ui" | undefined;
46
46
  databaseLibrary?: "unknown" | "drizzle" | "prisma" | "supabase" | undefined;
47
- databaseProvider?: "unknown" | "sqlite" | "pg" | "mysql" | "mongodb" | undefined;
48
- linting?: "unknown" | "eslint" | undefined;
49
- formatting?: "unknown" | "biome" | undefined;
47
+ databaseProvider?: "unknown" | "pg" | "mysql" | "sqlite" | "mongodb" | undefined;
48
+ linting?: "eslint" | "unknown" | undefined;
49
+ formatting?: "biome" | "unknown" | undefined;
50
50
  payment?: "unknown" | "stripe" | undefined;
51
51
  monitoring?: "unknown" | "sentry" | undefined;
52
52
  logging?: "unknown" | "axiom" | undefined;
@@ -75,7 +75,7 @@ export declare const defineConfigRse: (userConfig?: Partial<RseConfig>) => {
75
75
  indentStyle?: "space" | "tab" | undefined;
76
76
  quoteMark?: "single" | "double" | undefined;
77
77
  semicolons?: boolean | undefined;
78
- trailingComma?: "all" | "none" | "es5" | undefined;
78
+ trailingComma?: "none" | "es5" | "all" | undefined;
79
79
  bracketSpacing?: boolean | undefined;
80
80
  arrowParens?: "always" | "avoid" | undefined;
81
81
  tabWidth?: number | undefined;
@@ -83,7 +83,7 @@ export declare const defineConfigRse: (userConfig?: Partial<RseConfig>) => {
83
83
  dontRemoveComments?: boolean | undefined;
84
84
  shouldAddComments?: boolean | undefined;
85
85
  typeOrInterface?: "type" | "interface" | "mixed" | undefined;
86
- importOrRequire?: "import" | "require" | "mixed" | undefined;
86
+ importOrRequire?: "mixed" | "import" | "require" | undefined;
87
87
  cjsToEsm?: boolean | undefined;
88
88
  modernize?: {
89
89
  replaceFs?: boolean | undefined;
@@ -96,7 +96,7 @@ export declare const defineConfigRse: (userConfig?: Partial<RseConfig>) => {
96
96
  importSymbol?: string | undefined;
97
97
  } | undefined;
98
98
  monorepo?: {
99
- type?: "bun" | "none" | "turborepo" | "nx" | "pnpm" | undefined;
99
+ type?: "none" | "bun" | "turborepo" | "nx" | "pnpm" | undefined;
100
100
  packages?: string[] | undefined;
101
101
  sharedPackages?: string[] | undefined;
102
102
  } | undefined;
@@ -111,9 +111,9 @@ export declare const defineConfigRse: (userConfig?: Partial<RseConfig>) => {
111
111
  customReposOnNewProject?: boolean | undefined;
112
112
  envComposerOpenBrowser?: boolean | undefined;
113
113
  repoBranch?: string | undefined;
114
- repoPrivacy?: "private" | "public" | "unknown" | undefined;
114
+ repoPrivacy?: "unknown" | "public" | "private" | undefined;
115
115
  projectArchitecture?: "unknown" | "fullstack" | "separated" | undefined;
116
- projectRuntime?: "bun" | "node" | "deno" | undefined;
116
+ projectRuntime?: "node" | "bun" | "deno" | undefined;
117
117
  skipPromptsUseAutoBehavior?: boolean | undefined;
118
118
  deployBehavior?: "prompt" | "autoYes" | "autoNo" | undefined;
119
119
  depsBehavior?: "prompt" | "autoYes" | "autoNo" | undefined;
@@ -8,7 +8,7 @@ export * from "./rse-impl/rse-default";
8
8
  export * from "./rse-impl/rse-define";
9
9
  export * from "./rse-impl/rse-detect";
10
10
  export * from "./rse-impl/rse-gen-cfg";
11
- export * from "./rse-impl/rse-inject";
11
+ export * from "./rse-impl/rse-comments";
12
12
  export * from "./rse-impl/rse-migrate";
13
13
  export * from "./rse-impl/rse-path";
14
14
  export * from "./rse-impl/rse-prompts";
@@ -8,7 +8,7 @@ export * from "./rse-impl/rse-default.js";
8
8
  export * from "./rse-impl/rse-define.js";
9
9
  export * from "./rse-impl/rse-detect.js";
10
10
  export * from "./rse-impl/rse-gen-cfg.js";
11
- export * from "./rse-impl/rse-inject.js";
11
+ export * from "./rse-impl/rse-comments.js";
12
12
  export * from "./rse-impl/rse-migrate.js";
13
13
  export * from "./rse-impl/rse-path.js";
14
14
  export * from "./rse-impl/rse-prompts.js";
@@ -0,0 +1,63 @@
1
+ /**
2
+ * inject-impl-mod.ts
3
+ * -----------
4
+ * Utility for injecting content into files at specific line/column positions.
5
+ *
6
+ * Fully async -– works with Node, Bun, and other
7
+ * runtimes that support the `fs/promises` API.
8
+ *
9
+ * @author blefnk
10
+ */
11
+ export interface InjectionConfig {
12
+ /** Absolute or relative path to target file. */
13
+ filePath: string;
14
+ /** 1-based line number (1 == first visible line in editors) */
15
+ line: number;
16
+ /** 1-based column number (1 == first visible column in editors) */
17
+ column?: number;
18
+ /** String or array of strings to inject. */
19
+ content: string | string[];
20
+ /** If `true`, inserts string (or first element of array) content on a new line AFTER the target line. */
21
+ createNewLine?: boolean;
22
+ /** Configuration for comment wrapping. */
23
+ commentsMode?: {
24
+ /** Whether to wrap content in comments. */
25
+ activate: boolean;
26
+ /** Whether to use JSDoc style for multiline comments. */
27
+ useJsdocForMultiline?: boolean;
28
+ };
29
+ }
30
+ export interface InjectionResult {
31
+ /** Absolute or relative path to target file. */
32
+ filePath: string;
33
+ /** Whether the injection was successful. */
34
+ success: boolean;
35
+ /** Error message if injection failed. */
36
+ error?: string;
37
+ /** Generated source map if available. */
38
+ sourcemap?: string;
39
+ }
40
+ /**
41
+ * Injects content into the given file at the requested location.
42
+ *
43
+ * @param filePath Absolute or relative path to target file.
44
+ * @param line 1-based line number (1 == first visible line in editors, internally == 0).
45
+ * @param column 1-based column number (optional, 1 == first visible column in editors, internally == 0).
46
+ * @param content String or array of strings to inject.
47
+ * @param createNewLine If `true`, inserts string (or first element of array) content on a new line AFTER the target line.
48
+ * @param commentsMode If `true`, wraps injected content in file-type comments.
49
+ * @param generateSourceMap If `true`, generates a source map for the transformation.
50
+ *
51
+ * @returns `true` on success, `false` on failure (errors are logged).
52
+ */
53
+ export declare function injectAtLocation(filePath: string, line: number, column: number | undefined, content: string | string[], createNewLine?: boolean, commentsMode?: {
54
+ activate: boolean;
55
+ }, generateSourceMap?: boolean): Promise<boolean>;
56
+ /**
57
+ * Processes multiple injections efficiently by grouping by file and applying in reverse order.
58
+ *
59
+ * @param configs Array of {@link InjectionConfig}.
60
+ * @param generateSourceMaps If `true`, generates source maps for transformations.
61
+ * @returns Array of {@link InjectionResult} in the same order as `configs`.
62
+ */
63
+ export declare function injectMultiple(configs: InjectionConfig[], generateSourceMaps?: boolean): Promise<InjectionResult[]>;
@@ -0,0 +1,237 @@
1
+ import MagicString from "magic-string";
2
+ import { promises as fs } from "node:fs";
3
+ import * as path from "node:path";
4
+ import { isBinaryExt } from "../../utils/binary.js";
5
+ export async function injectAtLocation(filePath, line, column, content, createNewLine = false, commentsMode = { activate: false }, generateSourceMap = false) {
6
+ try {
7
+ await validateInput(filePath, line, column);
8
+ const originalContent = await fs.readFile(filePath, "utf8");
9
+ const magicString = new MagicString(originalContent, {
10
+ filename: path.basename(filePath)
11
+ });
12
+ const pieces = Array.isArray(content) ? content : [content];
13
+ const preparedContent = prepareContentForInjection(
14
+ pieces,
15
+ commentsMode,
16
+ path.extname(filePath),
17
+ createNewLine
18
+ );
19
+ const success = injectWithMagicString(
20
+ magicString,
21
+ originalContent,
22
+ line,
23
+ column,
24
+ preparedContent,
25
+ createNewLine
26
+ );
27
+ if (!success) return false;
28
+ const result = magicString.toString();
29
+ await fs.writeFile(filePath, result, "utf8");
30
+ if (generateSourceMap) {
31
+ const map = magicString.generateMap({
32
+ source: filePath,
33
+ file: `${filePath}.map`,
34
+ includeContent: true,
35
+ hires: true
36
+ });
37
+ await fs.writeFile(`${filePath}.map`, map.toString(), "utf8");
38
+ }
39
+ return true;
40
+ } catch (err) {
41
+ console.error(`[injector] ${filePath}: ${err.message}`);
42
+ return false;
43
+ }
44
+ }
45
+ export async function injectMultiple(configs, generateSourceMaps = false) {
46
+ const configsByFile = /* @__PURE__ */ new Map();
47
+ configs.forEach((config, index) => {
48
+ if (!configsByFile.has(config.filePath)) {
49
+ configsByFile.set(config.filePath, []);
50
+ }
51
+ configsByFile.get(config.filePath)?.push({ config, originalIndex: index });
52
+ });
53
+ const results = new Array(configs.length);
54
+ for (const [filePath, fileConfigs] of configsByFile) {
55
+ try {
56
+ const firstConfig = fileConfigs[0]?.config;
57
+ if (!firstConfig) {
58
+ throw new Error(`No valid configs found for file: ${filePath}`);
59
+ }
60
+ await validateInput(firstConfig.filePath, firstConfig.line, firstConfig.column);
61
+ const originalContent = await fs.readFile(filePath, "utf8");
62
+ const magicString = new MagicString(originalContent, {
63
+ filename: path.basename(filePath)
64
+ });
65
+ const sortedConfigs = [...fileConfigs].sort((a, b) => {
66
+ const aLine = a.config.line;
67
+ const bLine = b.config.line;
68
+ if (aLine !== bLine) return bLine - aLine;
69
+ const aCol = a.config.column ?? Number.MAX_SAFE_INTEGER;
70
+ const bCol = b.config.column ?? Number.MAX_SAFE_INTEGER;
71
+ return bCol - aCol;
72
+ });
73
+ let allSuccessful = true;
74
+ for (const { config, originalIndex } of sortedConfigs) {
75
+ const { line, column, content, createNewLine, commentsMode } = config;
76
+ const pieces = Array.isArray(content) ? content : [content];
77
+ const preparedContent = prepareContentForInjection(
78
+ pieces,
79
+ commentsMode,
80
+ path.extname(filePath),
81
+ createNewLine ?? false
82
+ );
83
+ const success = injectWithMagicString(
84
+ magicString,
85
+ originalContent,
86
+ line,
87
+ column,
88
+ preparedContent,
89
+ createNewLine ?? false
90
+ );
91
+ results[originalIndex] = success ? { filePath, success } : {
92
+ filePath,
93
+ success: false,
94
+ error: `Injection failed for ${filePath} at line ${line}`
95
+ };
96
+ if (!success) {
97
+ allSuccessful = false;
98
+ }
99
+ }
100
+ if (allSuccessful) {
101
+ const result = magicString.toString();
102
+ await fs.writeFile(filePath, result, "utf8");
103
+ if (generateSourceMaps) {
104
+ const map = magicString.generateMap({
105
+ source: filePath,
106
+ file: `${filePath}.map`,
107
+ includeContent: true,
108
+ hires: true
109
+ });
110
+ await fs.writeFile(`${filePath}.map`, map.toString(), "utf8");
111
+ }
112
+ }
113
+ } catch (err) {
114
+ for (const { originalIndex } of fileConfigs) {
115
+ results[originalIndex] = {
116
+ filePath,
117
+ success: false,
118
+ error: `File processing failed: ${err.message}`
119
+ };
120
+ }
121
+ }
122
+ }
123
+ return results;
124
+ }
125
+ async function validateInput(filePath, line, column) {
126
+ await fs.access(filePath).catch(() => {
127
+ throw new Error("File does not exist.");
128
+ });
129
+ if (await isBinaryExt(filePath)) {
130
+ throw new Error("Cannot inject into binary files.");
131
+ }
132
+ if (!Number.isInteger(line) || line < 1)
133
+ throw new Error("`line` must be a positive 1-based integer.");
134
+ if (column !== void 0 && (!Number.isInteger(column) || column < 1))
135
+ throw new Error("`column` must be a positive 1-based integer when provided.");
136
+ }
137
+ function getCharacterIndex(content, line1Based, column1Based) {
138
+ const lines = content.split(/\r?\n/);
139
+ const eolLength = content.includes("\r\n") ? 2 : 1;
140
+ while (lines.length < line1Based) {
141
+ lines.push("");
142
+ }
143
+ let index = 0;
144
+ for (let i = 0; i < line1Based - 1; i++) {
145
+ index += lines[i]?.length ?? 0;
146
+ if (i < lines.length - 1) index += eolLength;
147
+ }
148
+ const targetLine = lines[line1Based - 1] || "";
149
+ const lineStart = index;
150
+ const lineEnd = lineStart + targetLine.length;
151
+ if (column1Based !== void 0) {
152
+ const colIndex = Math.min(column1Based - 1, targetLine.length);
153
+ index += colIndex;
154
+ } else {
155
+ index = lineEnd;
156
+ }
157
+ return { index, lineEnd, lineStart };
158
+ }
159
+ function prepareContentForInjection(pieces, commentsMode, ext, createNewLine) {
160
+ let preparedPieces = pieces.slice();
161
+ if (commentsMode?.activate) {
162
+ preparedPieces = applyCommentWrapping(preparedPieces, commentsMode, ext);
163
+ }
164
+ let result = preparedPieces.join("\n");
165
+ if (createNewLine && result) {
166
+ result = "\n" + result;
167
+ }
168
+ return result;
169
+ }
170
+ function applyCommentWrapping(pieces, commentsMode, ext) {
171
+ const { lineComment, blockStart, blockEnd } = getCommentSymbols(ext);
172
+ if (pieces.length === 1) {
173
+ return pieces.map((p) => ` ${lineComment} ${p}`);
174
+ }
175
+ const isJsdoc = commentsMode.useJsdocForMultiline;
176
+ const processedPieces = pieces.map((p) => p === "" ? " " : p);
177
+ return [
178
+ ` ${blockStart}${isJsdoc ? "*" : ""} ${processedPieces[0]}`,
179
+ ...processedPieces.slice(1, -1).map((p) => ` ${isJsdoc ? "*" : ""} ${p}`),
180
+ ` ${isJsdoc ? "*" : ""} ${processedPieces[processedPieces.length - 1]} ${blockEnd}`
181
+ ];
182
+ }
183
+ function injectWithMagicString(magicString, originalContent, line1Based, column1Based, preparedContent, createNewLine) {
184
+ try {
185
+ const { index, lineEnd, lineStart } = getCharacterIndex(
186
+ originalContent,
187
+ line1Based,
188
+ column1Based
189
+ );
190
+ const currentLength = originalContent.length;
191
+ if (index > currentLength) {
192
+ const linesNeeded = Math.ceil((index - currentLength) / 50);
193
+ const extension = "\n".repeat(linesNeeded);
194
+ magicString.append(extension);
195
+ }
196
+ if (createNewLine) {
197
+ if (column1Based !== void 0) {
198
+ const currentLineContent = originalContent.split(/\r?\n/)[line1Based - 1] || "";
199
+ const beforeColumn = currentLineContent.slice(0, column1Based - 1);
200
+ const afterColumn = currentLineContent.slice(column1Based - 1);
201
+ const replacement = beforeColumn + "\n" + preparedContent + (afterColumn ? "\n" + afterColumn : "");
202
+ magicString.overwrite(lineStart, lineEnd, replacement);
203
+ } else {
204
+ magicString.appendRight(lineEnd, preparedContent);
205
+ }
206
+ } else {
207
+ magicString.appendRight(index, preparedContent);
208
+ }
209
+ return true;
210
+ } catch (err) {
211
+ console.error(`[injector] MagicString injection failed: ${err.message}`);
212
+ return false;
213
+ }
214
+ }
215
+ function getCommentSymbols(ext) {
216
+ const map = {
217
+ ".js": { line: "//", blockStart: "/*", blockEnd: "*/" },
218
+ ".ts": { line: "//", blockStart: "/*", blockEnd: "*/" },
219
+ ".jsx": { line: "//", blockStart: "/*", blockEnd: "*/" },
220
+ ".tsx": { line: "//", blockStart: "/*", blockEnd: "*/" },
221
+ ".css": { line: "//", blockStart: "/*", blockEnd: "*/" },
222
+ ".scss": { line: "//", blockStart: "/*", blockEnd: "*/" },
223
+ ".html": { line: "//", blockStart: "<!--", blockEnd: "-->" },
224
+ ".py": { line: "#", blockStart: '"""', blockEnd: '"""' },
225
+ ".sh": { line: "#", blockStart: ": <<'BLOCK'", blockEnd: "BLOCK" },
226
+ ".yaml": { line: "#", blockStart: "# ---", blockEnd: "# ---" },
227
+ ".yml": { line: "#", blockStart: "# ---", blockEnd: "# ---" },
228
+ ".json": { line: "//", blockStart: "/*", blockEnd: "*/" },
229
+ ".jsonc": { line: "//", blockStart: "/*", blockEnd: "*/" }
230
+ };
231
+ const symbols = map[ext.toLowerCase()] ?? { line: "//", blockStart: "/*", blockEnd: "*/" };
232
+ return {
233
+ lineComment: symbols.line ?? "//",
234
+ blockStart: symbols.blockStart,
235
+ blockEnd: symbols.blockEnd
236
+ };
237
+ }
@@ -1,11 +1,9 @@
1
1
  import { endPrompt, startPrompt } from "@reliverse/rempts";
2
- const version = "1.7.21";
2
+ const version = "1.7.23";
3
3
  export async function showStartPrompt(isDev) {
4
4
  await startPrompt({
5
5
  titleColor: "inverse",
6
6
  clearConsole: false,
7
- // packageName: getPkgName(),
8
- // packageVersion: getPkgVersion(),
9
7
  packageName: "dler",
10
8
  packageVersion: version,
11
9
  isDev
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Spell runner – walks a directory tree, finds
3
+ * magic-comment directives and executes them.
4
+ *
5
+ * Usage example:
6
+ * await applyMagicSpells(["dist-jsr"]);
7
+ * await applyMagicSpells(["dist-libs/sdk"]);
8
+ * await applyMagicSpells(["dist-npm", "dist-jsr", "dist-libs"]);
9
+ * await applyMagicSpells(["custom-output/my-lib"]); // For custom targets, magic directives are processed directly in the target files
10
+ */
11
+ export interface ApplyMagicSpellsOptions {
12
+ /** Absolute or cwd-relative root directory to process */
13
+ dir: string;
14
+ /** Number of files to process in parallel */
15
+ concurrency?: number;
16
+ /** Number of files to process in each batch */
17
+ batchSize?: number;
18
+ /** Whether to stop on first error */
19
+ stopOnError?: boolean;
20
+ /** Whether to copy files from src before processing */
21
+ copyFileWithDirectivesFromSrcBeforeProcessing?: boolean;
22
+ /** Custom output paths mapping for non-standard directories */
23
+ customOutputPaths?: Record<string, string>;
24
+ }
25
+ export interface ApplyMagicSpellsResult {
26
+ /** All processed files */
27
+ processedFiles: string[];
28
+ }
29
+ /**
30
+ * Processes files in specified output directories by applying magic directives
31
+ * For dist targets, first scans src directory for files with magic directives, then processes corresponding output files
32
+ * For custom targets, processes magic directives directly in the target files
33
+ * @param targets Array of output targets in format "dist-npm", "dist-jsr", "dist-libs" or "dist-libs/lib-name" or any custom path
34
+ * @param options Configuration options for processing
35
+ * @returns Object containing arrays of processed files and processed .d.ts files
36
+ */
37
+ export declare function applyMagicSpells(targets: string[], options?: Partial<ApplyMagicSpellsOptions>): Promise<ApplyMagicSpellsResult>;
38
+ /**
39
+ * Gets all available registries across all libraries
40
+ * @returns Array of unique registry names found across all libraries
41
+ */
42
+ export declare function getAllAvailableRegistries(): Promise<string[]>;
43
+ /**
44
+ * Information about a file containing magic spells
45
+ */
46
+ export interface FileWithSpells {
47
+ /** Absolute path to the file */
48
+ path: string;
49
+ /** Line numbers where spells were found (1-based) */
50
+ spellLines: number[];
51
+ }
52
+ /**
53
+ * Scans directories for files containing magic spells
54
+ * @param dirs Array of directories to scan (absolute or cwd-relative paths)
55
+ * @param options Configuration options for scanning
56
+ * @returns Array of files containing magic spells with their line numbers
57
+ */
58
+ export declare function getFilesWithMagicSpells(dirs: string[], options?: {
59
+ /** Whether to stop on first error */
60
+ stopOnError?: boolean;
61
+ /** Whether to exclude spell implementation files */
62
+ excludeSpellImplementation?: boolean;
63
+ }): Promise<FileWithSpells[]>;