@frsource/frs-replace 4.1.0 → 5.0.0

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/bin/cli.mjs ADDED
@@ -0,0 +1,213 @@
1
+ #!/usr/bin/env node
2
+ import { resolve } from 'path';
3
+ import yargs from 'yargs/yargs';
4
+ import { hideBin } from 'yargs/helpers';
5
+ import { sync } from '../dist/index.mjs';
6
+
7
+ (~process.argv.indexOf('--no-stdin')
8
+ ? Promise.resolve()
9
+ : (await import('get-stdin')).default()
10
+ ).then(async (stdin) => {
11
+ const isPiped = !!stdin;
12
+
13
+ if (isPiped) {
14
+ process.argv.push('-c');
15
+ process.argv.push(stdin); // threat piped data as value for --content option
16
+ }
17
+
18
+ const isContentPresent = !!(
19
+ ~process.argv.indexOf('--content') || ~process.argv.indexOf('-c')
20
+ );
21
+ const isHelpPresent = !!(
22
+ ~process.argv.indexOf('--help') || ~process.argv.indexOf('-h')
23
+ );
24
+
25
+ const argv = await yargs(hideBin(process.argv))
26
+ .parserConfiguration({
27
+ 'camel-case-expansion': false,
28
+ })
29
+ .scriptName('frs-replace')
30
+ .usage(
31
+ '$0 <needle> <replacement> [options]',
32
+ 'Replace matching parts of string with replacement string/function',
33
+ (yargs) =>
34
+ yargs
35
+ .positional('needle', {
36
+ describe:
37
+ 'String which is passed as a first parameter to RegExp constructor',
38
+ type: 'string',
39
+ demand: true,
40
+ })
41
+ .positional('replacement', {
42
+ describe:
43
+ 'String or path to replacement function file (see --replace-fn switch for details)',
44
+ type: 'string',
45
+ demand: true,
46
+ })
47
+ .example(
48
+ '$0 a b -i foo.js -o foo_replaced.js',
49
+ 'Replaces all "a" occurences with "b" from given foo.js and save result to foo_replaced.js',
50
+ )
51
+ .example(
52
+ '<read file> | $0 a b > <output-file-path>',
53
+ 'Replaces all "a" occurences with "b" from stream and save it to output file',
54
+ )
55
+ .example(
56
+ '<read file> | $0 a b | <next-command>',
57
+ 'Replaces all "a" occurences with "b" from stream and pass it through the stream to next command',
58
+ )
59
+ .example(
60
+ '$0 a b -i foo.js | <next-command>',
61
+ 'Both pipe & options styles can be mixed together, here - getting input from "i" argument and passing output down the stream to next command',
62
+ )
63
+ .example(
64
+ '$0 a b --content abcd -o foo_replaced.js',
65
+ 'Replace all "a" occurences with "b" in given "abcd" and save result (which is "bbcd") to foo_replaced.js',
66
+ ),
67
+ )
68
+
69
+ .option('f', {
70
+ alias: 'flags',
71
+ describe:
72
+ 'RegExp flags used together with `needle` positional (supporting g, i & m)',
73
+ nargs: 1,
74
+ default: 'g',
75
+
76
+ choices: /** @type {const} */ ([
77
+ '',
78
+ 'g',
79
+ 'm',
80
+ 'i',
81
+ 'gm',
82
+ 'gi',
83
+ 'mi',
84
+ 'mg',
85
+ 'ig',
86
+ 'im',
87
+ 'gmi',
88
+ 'gim',
89
+ 'mig',
90
+ 'mgi',
91
+ 'igm',
92
+ 'img',
93
+ ]),
94
+ coerce: (arg) => arg.trim(),
95
+ })
96
+ .option('i', {
97
+ demandOption: !isContentPresent && !isHelpPresent,
98
+ alias: 'input',
99
+ describe:
100
+ 'Path to files or fast-glob pattern pointing to files to read & replace from',
101
+ array: true,
102
+ string: true,
103
+ })
104
+
105
+ .option('i-read-opts', {
106
+ implies: 'i',
107
+ describe: 'Passed to fs.readFileSync when reading input file',
108
+ defaultDescription: 'utf8', // will use node's default value
109
+ })
110
+
111
+ .option('i-glob-opts', {
112
+ describe: 'Passed to fast-glob.sync when resolving glob patterns',
113
+ implies: 'i',
114
+ })
115
+
116
+ .option('stdin', {
117
+ describe:
118
+ 'Wait for stdin input (should be set to false when used in non-interactive terminals)',
119
+ boolean: true,
120
+ default: true,
121
+ })
122
+
123
+ .option('c', {
124
+ demandOption: isContentPresent,
125
+ alias: 'content',
126
+ describe:
127
+ 'Content to be replaced (takes precedence over stream & file input)',
128
+ string: true,
129
+ nargs: 1,
130
+ })
131
+
132
+ .option('s', {
133
+ alias: 'strategy',
134
+ describe: `output file generation strategy.
135
+ \`join\` - join all input files and saves single file using "output" option as it's path,
136
+ \`preserve-structure\` - when replacing files content copies them over to the directory specified by "output" option.
137
+ \`flatten\` - same as \`preserve-structure\` but flattens the directory structure`,
138
+ nargs: 1,
139
+ choices: /** @type {const} */ (['join', 'flatten', 'preserve-structure']),
140
+ default: 'join',
141
+ coerce: (arg) => arg.trim(),
142
+ })
143
+
144
+ .option('o', {
145
+ alias: 'output',
146
+ describe:
147
+ "Output file name/path (replaces the file if it already exists and creates any intermediate directories if they don't already exist) or (when used together with `strategy` = `flatten` or `preserve-structure`) path to the output directory",
148
+ string: true,
149
+ nargs: 1,
150
+ })
151
+
152
+ .option('o-write-opts', {
153
+ describe: "Passed as options argument of write's .sync method",
154
+ defaultDescription: 'utf8', // will use node's default value
155
+ implies: 'o',
156
+ })
157
+
158
+ .option('o-join-str', {
159
+ describe:
160
+ 'String used when joining multiple files (use it together with either `output` or `stdout` option)',
161
+ default: undefined,
162
+ defaultDescription: 'newline (\\n)', // will use node's default value
163
+ })
164
+
165
+ .option('stdout', {
166
+ describe: 'Force sending output on stdout',
167
+ boolean: true,
168
+ default: isPiped,
169
+ defaultDescription: 'true when piped input present, false otherwise',
170
+ })
171
+
172
+ .option('r', {
173
+ alias: 'replace-fn',
174
+ describe:
175
+ 'Treat replacement argument as path to file containing replacement function',
176
+ boolean: true,
177
+ })
178
+
179
+ .help('h')
180
+ .alias('h', 'help')
181
+
182
+ .version('v')
183
+ .alias('v', 'version')
184
+
185
+ .epilog('Brought to you with open-source love by FRSOURCE').argv;
186
+
187
+ try {
188
+ const result = sync({
189
+ input: argv.i,
190
+ inputReadOptions: argv['i-read-opts'],
191
+ inputGlobOptions:
192
+ /** @type import('fast-glob').Options */ argv['i-glob-opts'],
193
+ content: argv.c,
194
+ strategy: argv.s,
195
+ output: argv.o,
196
+ outputWriteOptions: argv['o-write-opts'],
197
+ outputJoinString: argv['o-join-str'],
198
+ needle: new RegExp(argv.needle, argv.f),
199
+ replacement: argv.r
200
+ ? (await import(resolve(argv.replacement))).default
201
+ : argv.replacement,
202
+ });
203
+
204
+ if (argv.stdout) {
205
+ process.stdout.write(result[0][1]);
206
+ }
207
+
208
+ return process.exit();
209
+ } catch (e) /* c8 ignore next */ {
210
+ process.stderr.write(e.toString());
211
+ return process.exit(1);
212
+ }
213
+ });
@@ -0,0 +1,3 @@
1
+ import type { Args, FileResult } from './types.js';
2
+ declare const _default: ({ strategy, needle, replacement, ...args }: Args) => Promise<FileResult[]>;
3
+ export default _default;
@@ -0,0 +1,3 @@
1
+ export * from './types.js';
2
+ export { default as sync } from './sync.js';
3
+ export { default as async } from './async.js';
package/dist/index.mjs ADDED
@@ -0,0 +1,2 @@
1
+ import{normalize as t,sep as e,dirname as n,join as r}from"path";import{readFileSync as i,mkdirSync as o,writeFileSync as u,readFile as s,promises as a}from"fs";import l from"fast-glob";function p(t,e){if(null==t)return{};var n={};for(var r in t)if(Object.prototype.hasOwnProperty.call(t,r)){if(e.indexOf(r)>=0)continue;n[r]=t[r]}return n}const c=t=>{throw new Error(`@frsource/frs-replace :: ${t}`)},f=(t,e)=>"string"==typeof t?n=>{const r=t.length;let i,o="",u=0;for(;-1!==(i=n.indexOf(t,u));)o+=n.slice(u,i)+e,u=i+r;return o+n.slice(u,n.length)}:n=>n.replace(t,e),d=["strategy","needle","replacement"],v=(t,e,r)=>{o(n(t),{recursive:!0}),u(t,e,r)},g={join:(t,e)=>{var n;let r=(null==(n=t[0])?void 0:n[1])||"";for(let n=1;n<t.length;++n)r+=e+t[n][1];return[[["",r]]]},flatten:t=>{for(let n=0;n<t.length;++n){const r=t[n][0];t[n][0]=r.substring(r.lastIndexOf(e))}return[t]},"preserve-structure":(...t)=>t},m=(t,e,n)=>{for(let i=0;i<t.length;++i){const o=t[i];o[0]=r(e,o[0]),v(o[0],o[1],n)}return t},w={join:(t,e,n)=>(v(e,t[0][1],n),t[0][0]=e,t),flatten:m,"preserve-structure":m};var O=e=>{var n;let r,{strategy:o="join",needle:u,replacement:s}=e,a=p(e,d);const v=f(u,s);if("content"in a&&void 0!==a.content)r=[["",v(a.content)]];else if("input"in a&&void 0!==a.input){null!=a.inputReadOptions||(a.inputReadOptions="utf8"),r=[];const t=l.sync(a.input,a.inputGlobOptions),e=t.length;for(let n=0;n<e;++n){const e=t[n];r.push([e,v(i(e,a.inputReadOptions).toString())])}}else c("at least one input source must be defined! Use either 'content' or 'input' param.");g[o]||c('unsupported strategy used! Possible values are: "join", "preserve-structure" or "flatten"');const m=null!=(n="outputJoinString"in a?a.outputJoinString:void 0)?n:"\n";return[r]=g[o](r,m),"output"in a&&void 0!==a.output&&(null!=a.outputWriteOptions||(a.outputWriteOptions="utf8"),r=w[o](r,t(a.output),a.outputWriteOptions)),r};const y=["strategy","needle","replacement"],h=async(t,e,r)=>{await a.mkdir(n(t),{recursive:!0}),await a.writeFile(t,e,r)},b={join:async(t,e)=>[await Promise.all(await t).then(t=>{const n=t.length;let r=t[0]&&t[0][1]||"";for(let i=1;i<n;++i)r+=e+t[i][1];return["",r]})],flatten:async t=>await Promise.all((await t).map(async t=>((t=await t)[0]=t[0].substring(t[0].lastIndexOf(e)),t))),"preserve-structure":async t=>await Promise.all(await t)},j=async(t,e,n)=>Promise.all((await t).map(async t=>(t[0]=r(e,t[0]),await h(t[0],t[1],n),t))),P={join:async(t,e,n)=>{const r=(await t)[0];return await h(e,r[1],n),r[0]=e,[r]},flatten:j,"preserve-structure":j};var R=async e=>{var n;let r,{strategy:i="join",needle:o,replacement:u}=e,a=p(e,y);const d=f(o,u);if("content"in a&&void 0!==a.content)r=[["",d(a.content)]];else if("input"in a&&void 0!==a.input){null!=a.inputReadOptions||(a.inputReadOptions="utf8");const t=[],e=l.stream(a.input,a.inputGlobOptions);e.on("error",c),e.on("data",e=>t.push(new Promise((t,n)=>s(e,a.inputReadOptions,(r,i)=>{if(r)return n(r);t([e,d(i.toString())])})))),r=new Promise(n=>e.once("end",()=>n(t))).catch(c)}else c("at least one input source must be defined!");b[i]||c('unsupported strategy used! Possible values are: "join", "preserve-structure" or "flatten"');const v=null!=(n="outputJoinString"in a?a.outputJoinString:void 0)?n:"\n";let g=await b[i](r,v);return"output"in a&&void 0!==a.output&&(null!=a.outputWriteOptions||(a.outputWriteOptions="utf8"),g=await P[i](g,t(a.output),a.outputWriteOptions)),g};export{R as async,O as sync};
2
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","sources":["../src/utils.ts","../src/sync.ts","../src/async.ts"],"sourcesContent":["import type { Args } from './types.js';\n\nexport const writeError = (msg: string) => {\n throw new Error(`@frsource/frs-replace :: ${msg}`);\n};\n\nexport const getReplaceFn = (needle: Args['needle'], replacement: string) =>\n typeof needle === 'string'\n ? (content: string) => {\n const needleLen = needle.length;\n let result = '';\n let i;\n let endIndex = 0;\n\n while ((i = content.indexOf(needle, endIndex)) !== -1) {\n result += content.slice(endIndex, i) + replacement;\n endIndex = i + needleLen;\n }\n\n return result + content.slice(endIndex, content.length);\n }\n : (content: string) => content.replace(needle, replacement);\n","import { sep, join, normalize, dirname } from 'path';\nimport { readFileSync, writeFileSync, mkdirSync } from 'fs';\nimport fastGlob from 'fast-glob';\nimport { writeError, getReplaceFn } from './utils.js';\nimport type {\n Strategy,\n InputStrategyFnSync,\n OutputStrategyFnSync,\n Args,\n FileResult,\n} from './types.js';\n\nconst writeSync = (\n path: string,\n data: string,\n options: Parameters<typeof writeFileSync>[2],\n) => {\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, data, options);\n};\n\nconst inputStrategyMap = {\n join: (results, outputJoinString) => {\n let result = results[0]?.[1] || '';\n for (let i = 1; i < results.length; ++i) {\n result += outputJoinString + results[i][1];\n }\n return [[['', result]]];\n },\n flatten: (results) => {\n for (let i = 0; i < results.length; ++i) {\n const result = results[i][0];\n results[i][0] = result.substring(result.lastIndexOf(sep));\n }\n return [results];\n },\n 'preserve-structure': (...args) => args,\n} satisfies Record<Strategy, InputStrategyFnSync>;\n\nconst multipleFilesOutputStrategy: OutputStrategyFnSync = (\n results,\n output,\n outputWriteOptions,\n) => {\n for (let i = 0; i < results.length; ++i) {\n const result = results[i];\n result[0] = join(output, result[0]);\n writeSync(result[0], result[1], outputWriteOptions);\n }\n return results;\n};\n\nconst outputStrategyMap = {\n join: (results, output, outputWriteOptions) => {\n writeSync(output, results[0][1], outputWriteOptions);\n results[0][0] = output;\n return results;\n },\n flatten: multipleFilesOutputStrategy,\n 'preserve-structure': multipleFilesOutputStrategy,\n} satisfies Record<Strategy, OutputStrategyFnSync>;\n\nexport default ({ strategy = 'join', needle, replacement, ...args }: Args) => {\n let results: FileResult[];\n const replaceFn = getReplaceFn(needle, replacement);\n\n if ('content' in args && args.content !== undefined) {\n results = [['', replaceFn(args.content)]];\n } else if ('input' in args && args.input !== undefined) {\n args.inputReadOptions ??= 'utf8';\n results = [];\n\n const files = fastGlob.sync(args.input, args.inputGlobOptions);\n const len = files.length;\n for (let i = 0; i < len; ++i) {\n const filePath = files[i];\n results.push([\n filePath,\n replaceFn(readFileSync(filePath, args.inputReadOptions).toString()),\n ]);\n }\n } else {\n writeError(\n \"at least one input source must be defined! Use either 'content' or 'input' param.\",\n );\n }\n\n if (!inputStrategyMap[strategy])\n writeError(\n 'unsupported strategy used! Possible values are: \"join\", \"preserve-structure\" or \"flatten\"',\n );\n\n const outputJoinString =\n ('outputJoinString' in args ? args.outputJoinString : undefined) ?? '\\n';\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n [results] = inputStrategyMap[strategy](results!, outputJoinString);\n\n if ('output' in args && args.output !== undefined) {\n args.outputWriteOptions ??= 'utf8';\n\n results = outputStrategyMap[strategy](\n results,\n normalize(args.output),\n args.outputWriteOptions,\n );\n }\n\n return results;\n};\n","import { sep, join, normalize, dirname } from 'path';\nimport { readFile, promises as fs } from 'fs';\nimport fastGlob from 'fast-glob';\nimport { writeError, getReplaceFn } from './utils.js';\nimport type {\n Strategy,\n InputStrategyFn,\n OutputStrategyFn,\n Args,\n FileResult,\n} from './types.js';\n\nconst write = async (\n path: string,\n data: string,\n options: Parameters<(typeof fs)['writeFile']>[2],\n) => {\n await fs.mkdir(dirname(path), { recursive: true });\n await fs.writeFile(path, data, options);\n};\n\nconst inputStrategyMap = {\n join: async (results, outputJoinString) => [\n await Promise.all(await results).then((results) => {\n const len = results.length;\n let result = (results[0] && results[0][1]) || '';\n for (let i = 1; i < len; ++i) {\n result += outputJoinString + results[i][1];\n }\n return ['', result];\n }),\n ],\n flatten: async (results) =>\n await Promise.all(\n (await results).map(async (result) => {\n result = await result;\n result[0] = result[0].substring(result[0].lastIndexOf(sep));\n return result;\n }),\n ),\n 'preserve-structure': async (results) => await Promise.all(await results),\n} satisfies Record<Strategy, InputStrategyFn>;\n\nconst multipleFilesOutputStrategy: OutputStrategyFn = async (\n results,\n output,\n outputWriteOptions,\n) =>\n Promise.all(\n (await results).map(async (result) => {\n result[0] = join(output, result[0]);\n await write(result[0], result[1], outputWriteOptions);\n return result;\n }),\n );\n\nconst outputStrategyMap = {\n join: async (results, output, outputWriteOptions) => {\n const result = (await results)[0];\n await write(output, result[1], outputWriteOptions);\n result[0] = output;\n return [result];\n },\n flatten: multipleFilesOutputStrategy,\n 'preserve-structure': multipleFilesOutputStrategy,\n} satisfies Record<Strategy, OutputStrategyFn>;\n\nexport default async ({\n strategy = 'join',\n needle,\n replacement,\n ...args\n}: Args) => {\n let inputData: Parameters<InputStrategyFn>[0];\n const replaceFn = getReplaceFn(needle, replacement);\n\n if ('content' in args && args.content !== undefined) {\n inputData = [['', replaceFn(args.content)]];\n } else if ('input' in args && args.input !== undefined) {\n args.inputReadOptions ??= 'utf8';\n const replacePromises: Promise<FileResult>[] = [];\n\n const fileStream = fastGlob.stream(args.input, args.inputGlobOptions);\n fileStream.on('error', writeError);\n fileStream.on('data', (path) =>\n replacePromises.push(\n new Promise((resolve, reject) =>\n readFile(path, args.inputReadOptions, (error, data) => {\n /* c8 ignore next */\n if (error) return reject(error);\n\n resolve([path, replaceFn(data.toString())]);\n }),\n ),\n ),\n );\n inputData = new Promise<typeof replacePromises>((resolve) =>\n fileStream.once('end', () => resolve(replacePromises)),\n ).catch(writeError);\n } else {\n writeError('at least one input source must be defined!');\n }\n\n if (!inputStrategyMap[strategy])\n writeError(\n 'unsupported strategy used! Possible values are: \"join\", \"preserve-structure\" or \"flatten\"',\n );\n\n const outputJoinString =\n ('outputJoinString' in args ? args.outputJoinString : undefined) ?? '\\n';\n\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n let results = await inputStrategyMap[strategy](inputData!, outputJoinString);\n\n if ('output' in args && args.output !== undefined) {\n args.outputWriteOptions ??= 'utf8';\n\n results = await outputStrategyMap[strategy](\n results,\n normalize(args.output),\n args.outputWriteOptions,\n );\n }\n\n return results;\n};\n"],"names":["writeError","msg","Error","getReplaceFn","needle","replacement","content","needleLen","length","i","result","endIndex","indexOf","slice","replace","_excluded","writeSync","path","data","options","mkdirSync","dirname","recursive","writeFileSync","inputStrategyMap","join","results","outputJoinString","_results$","flatten","substring","lastIndexOf","sep","preserve-structure","args","multipleFilesOutputStrategy","output","outputWriteOptions","outputStrategyMap","_ref","_ref2","strategy","_objectWithoutPropertiesLoose","replaceFn","undefined","input","_args$inputReadOption","inputReadOptions","files","fastGlob","sync","inputGlobOptions","len","filePath","push","readFileSync","toString","_args$outputWriteOpti","normalize","write","async","fs","mkdir","writeFile","Promise","all","then","map","inputData","replacePromises","fileStream","stream","on","resolve","reject","readFile","error","once","catch"],"mappings":"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"}
package/dist/sync.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ import type { Args, FileResult } from './types.js';
2
+ declare const _default: ({ strategy, needle, replacement, ...args }: Args) => FileResult[];
3
+ export default _default;
@@ -0,0 +1,27 @@
1
+ /// <reference types="node" />
2
+ import type { readFileSync, writeFileSync } from 'fs';
3
+ import type { sync as globSync } from 'fast-glob';
4
+ export type Strategy = 'join' | 'flatten' | 'preserve-structure';
5
+ export type CommonArgs = {
6
+ strategy?: Strategy;
7
+ needle: string | RegExp;
8
+ replacement: string;
9
+ };
10
+ export type InputArgs = {
11
+ input: Parameters<typeof globSync>[0];
12
+ inputReadOptions?: Parameters<typeof readFileSync>[1];
13
+ inputGlobOptions?: Parameters<typeof globSync>[1];
14
+ } | {
15
+ content: string;
16
+ };
17
+ export type OutputArgs = {
18
+ output?: string;
19
+ outputWriteOptions?: Parameters<typeof writeFileSync>[2];
20
+ outputJoinString?: string;
21
+ } | object;
22
+ export type Args = CommonArgs & InputArgs & OutputArgs;
23
+ export type FileResult = [string, string];
24
+ export type InputStrategyFnSync = (results: FileResult[], outputJoinString: string) => [FileResult[]] | [FileResult[], string];
25
+ export type OutputStrategyFnSync = (results: FileResult[], output: string, outputWriteOptions: Parameters<typeof writeFileSync>[2]) => FileResult[];
26
+ export type InputStrategyFn = (results: Promise<Promise<FileResult>[]> | FileResult[], outputJoinString: string) => Promise<FileResult[]> | FileResult[];
27
+ export type OutputStrategyFn = (results: Promise<FileResult[]> | FileResult[], output: string, outputWriteOptions: Parameters<typeof writeFileSync>[2]) => Promise<FileResult[]>;
@@ -0,0 +1,3 @@
1
+ import type { Args } from './types.js';
2
+ export declare const writeError: (msg: string) => never;
3
+ export declare const getReplaceFn: (needle: Args['needle'], replacement: string) => (content: string) => string;
package/package.json CHANGED
@@ -1,29 +1,33 @@
1
1
  {
2
2
  "name": "@frsource/frs-replace",
3
- "version": "4.1.0",
3
+ "version": "5.0.0",
4
4
  "description": "Simple wrapper around javascript replace with CLI usage support!",
5
5
  "bin": {
6
- "frs-replace": "./bin/cli.js"
6
+ "frs-replace": "./bin/cli.mjs"
7
7
  },
8
- "main": "index.js",
9
- "repository": "https://github.com/FRSource/frs-replace.git",
8
+ "type": "module",
9
+ "source": "src/index.ts",
10
+ "main": "dist/index.mjs",
11
+ "types": "dist/index.d.ts",
12
+ "exports": {
13
+ ".": {
14
+ "types": "./dist/index.d.ts",
15
+ "default": "./dist/index.mjs"
16
+ },
17
+ "./*": "./*.mjs"
18
+ },
19
+ "repository": "https://github.com/FRSOURCE/frs-replace.git",
10
20
  "author": "Jakub Freisler <FRSgit@users.noreply.github.com>",
11
- "license": "Apache-2.0",
21
+ "license": "MIT",
22
+ "packageManager": "pnpm@8.15.9",
12
23
  "bugs": {
13
- "url": "https://github.com/FRSource/frs-replace/issues"
24
+ "url": "https://github.com/FRSOURCE/frs-replace/issues"
14
25
  },
15
- "homepage": "https://github.com/FRSource/frs-replace#readme",
26
+ "homepage": "https://github.com/FRSOURCE/frs-replace#readme",
16
27
  "files": [
17
- "bin/cli.js",
18
- "src/sync.js",
19
- "src/async.js",
20
- "src/utils.js",
21
- "sync.js",
22
- "async.js",
23
- "index.js",
24
- "LICENSE",
25
- "package.json",
26
- "yarn.lock"
28
+ "bin/cli.mjs",
29
+ "dist",
30
+ "package.json"
27
31
  ],
28
32
  "keywords": [
29
33
  "replace",
@@ -41,34 +45,52 @@
41
45
  "javascript"
42
46
  ],
43
47
  "scripts": {
44
- "prerelease": "yarn standard:fix && yarn test",
45
- "release": "standard-version",
46
- "postrelease": "git push --follow-tags origin master && yarn publish",
47
- "pretest": "standard",
48
- "test": "yarn test:unit --100",
49
- "posttest": "tap --coverage-report=html",
50
- "pretest:unit": "yarn standard:fix",
51
- "test:unit": "tap ./src/*.test.js ./bin/*.test.js -J",
52
- "test:unit:debug": "tap ./bin/cli.spec.test.js -J -R spec",
53
- "test:benchmark": "tap ./benchmark/*.benchmark.test.js --no-timeout --no-coverage",
54
- "test:benchmark:glob": "yarn test:benchmark --grep=\"/input as glob pattern/\"",
55
- "test:benchmark:string": "yarn test:benchmark --grep=\"/input & replacement as strings/\"",
56
- "standard:fix": "standard --fix"
48
+ "start": "pnpm clean && microbundle watch",
49
+ "build": "pnpm clean && microbundle src/index.ts --target node --compress -f modern",
50
+ "release": "semantic-release",
51
+ "release:ci": "pnpm release --yes",
52
+ "test": "vitest",
53
+ "coverage": "vitest --coverage",
54
+ "test:ci": "vitest run --coverage --allowOnly && vitest bench --run --allowOnly && TEST_TYPE=bench vitest run --allowOnly",
55
+ "eslint": "eslint .",
56
+ "prettier": "prettier . --check",
57
+ "lint": "pnpm eslint && pnpm prettier",
58
+ "fix": "pnpm eslint --fix && prettier . --write",
59
+ "bench": "vitest bench",
60
+ "test:bench": "TEST_TYPE=bench vitest",
61
+ "clean": "rimraf dist"
57
62
  },
58
63
  "devDependencies": {
59
- "perfy": "1.1.5",
60
- "replace": "1.2.2",
61
- "replace-in-file": "6.3.5",
62
- "replace-string": "3.1.0",
63
- "standard": "17.0.0",
64
- "standard-version": "9.5.0",
65
- "tap": "16.3.4",
66
- "tmp-promise": "3.0.3"
64
+ "@frsource/eslint-config": "1.7.0",
65
+ "@frsource/prettier-config": "1.5.0",
66
+ "@frsource/semantic-release-config": "^1.35.0",
67
+ "@semantic-release/changelog": "^6.0.3",
68
+ "@semantic-release/commit-analyzer": "^12.0.0",
69
+ "@semantic-release/git": "^10.0.1",
70
+ "@semantic-release/github": "^10.0.3",
71
+ "@semantic-release/npm": "^12.0.0",
72
+ "@semantic-release/release-notes-generator": "^13.0.0",
73
+ "@types/node": "20.11.1",
74
+ "@types/yargs": "^17.0.32",
75
+ "@vitest/coverage-v8": "1.6.0",
76
+ "@vitest/ui": "1.6.0",
77
+ "eslint": "^9.2.0",
78
+ "execa": "^9.5.2",
79
+ "globals": "^15.14.0",
80
+ "globals-vitest": "^1.6.0",
81
+ "microbundle": "^0.15.1",
82
+ "prettier": "^3.2.5",
83
+ "replace-in-file": "8.3.0",
84
+ "replace-string": "4.0.0",
85
+ "rimraf": "^5.0.5",
86
+ "semantic-release": "^23.0.8",
87
+ "tmp-promise": "3.0.3",
88
+ "typescript": "^5.4.5",
89
+ "vitest": "1.6.0"
67
90
  },
68
91
  "dependencies": {
69
- "fast-glob": "^3.1.0",
70
- "get-stdin": "^8.0.0",
71
- "write": "^2.0.0",
72
- "yargs": "^17.0.0"
92
+ "fast-glob": "3.3.2",
93
+ "get-stdin": "9.0.0",
94
+ "yargs": "17.7.2"
73
95
  }
74
96
  }
package/CHANGELOG.md DELETED
@@ -1,186 +0,0 @@
1
- # Changelog
2
-
3
- All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
-
5
- ## [4.1.0](https://github.com/FRSource/frs-replace/compare/v4.0.0...v4.1.0) (2023-02-05)
6
-
7
-
8
- ### Features
9
-
10
- * add stdin flag ([7574b49](https://github.com/FRSource/frs-replace/commit/7574b49274a525432f0353b0ce24c54e1514e580))
11
-
12
- ## [4.0.0](https://github.com/FRSource/frs-replace/compare/v3.0.3...v4.0.0) (2022-12-07)
13
-
14
-
15
- ### ⚠ BREAKING CHANGES
16
-
17
- * from now on replatement file path should be relative to projects' root
18
-
19
- Signed-off-by: Jakub Freisler <jakub@frsource.org>
20
-
21
- ### Features
22
-
23
- * require replacement method in scope of projects' root ([69fc050](https://github.com/FRSource/frs-replace/commit/69fc05009bf11230fbab73d649b4ce636ebbc8e2))
24
-
25
- ### [3.0.3](https://github.com/FRSource/frs-replace/compare/v3.0.2...v3.0.3) (2021-04-18)
26
-
27
- ### [3.0.2](https://github.com/FRSource/frs-replace/compare/v3.0.1...v3.0.2) (2021-04-18)
28
-
29
-
30
- ### Bug Fixes
31
-
32
- * cli release ([#122](https://github.com/FRSource/frs-replace/issues/122)) ([f813be4](https://github.com/FRSource/frs-replace/commit/f813be403baf49a0c8e8a878e8e4687a73a39832))
33
-
34
- ### [3.0.1](https://github.com/FRSource/frs-replace/compare/v3.0.0...v3.0.1) (2021-01-02)
35
-
36
- ### Bug Fixes
37
-
38
- * security update: ini ([#110](https://github.com/FRSource/frs-replace/pull/110))
39
- * updates: standard ([#107](https://github.com/FRSource/frs-replace/pull/107)), tap ([#106](https://github.com/FRSource/frs-replace/pull/106)), yargs ([#108](https://github.com/FRSource/frs-replace/pull/108)), standard-version ([#111](https://github.com/FRSource/frs-replace/pull/111))
40
-
41
- ## [3.0.0](https://github.com/FRSource/frs-replace/compare/v2.1.2...v3.0.0) (2020-10-27)
42
-
43
-
44
- ### ⚠ BREAKING CHANGES
45
-
46
- * from this version on Node.js api ALWAYS returns an array of replace result array, where replace result array follows the pattern: `[<replaced/new file path>, <replaced content>]`
47
- * renamed `regex` option to `needle`
48
- * renamed `inputJoinString` option to `outputJoinString`
49
-
50
- ### Features
51
-
52
- * different output strategies support ([#100](https://github.com/FRSource/frs-replace/issues/100)) ([d9cabac](https://github.com/FRSource/frs-replace/commit/d9cabac7d220a770637f5ef455e2770b1e28cdd4))
53
-
54
- ### [2.1.2](https://github.com/FRSource/frs-replace/compare/v2.1.1...v2.1.2) (2020-10-14)
55
-
56
- ### Bug Fixes
57
-
58
- * migration to yargs v16 ([yargs changelog](https://github.com/yargs/yargs/blob/master/CHANGELOG.md#1600-2020-09-09))
59
-
60
- ### [2.1.1](https://github.com/FRSource/frs-replace/compare/v2.1.0...v2.1.1) (2020-05-16)
61
-
62
-
63
- ### Bug Fixes
64
-
65
- * cli path for binary command ([2546905](https://github.com/FRSource/frs-replace/commit/254690572e86d31c60aaac5b234fbb6b5d11eabf))
66
-
67
- ## [2.1.0](https://github.com/FRSource/frs-replace/compare/v2.0.1...v2.1.0) (2020-05-15)
68
-
69
-
70
- ### Features
71
-
72
- * change npm package name - add it [@frsource](https://github.com/frsource) scope ([0208a90](https://github.com/FRSource/frs-replace/commit/0208a900c88f29ac167e06524ba583ea62eeb457))
73
- * rename FRS-replace to frs-replace ([#73](https://github.com/FRSource/frs-replace/issues/73)) ([8547685](https://github.com/FRSource/frs-replace/commit/8547685e09e133265ba493b8e5349adf8298b463))
74
-
75
- ### [2.0.1](https://github.com/FRSource/frs-replace/compare/v2.0.0...v2.0.1) (2019-11-01)
76
-
77
- ## [2.0.0](https://github.com/FRSource/frs-replace/compare/v1.0.1...v2.0.0) (2019-10-21)
78
-
79
-
80
- ### ⚠ BREAKING CHANGES
81
-
82
- * **package:** fast-glob does not support backslashes in glob patterns anymore, always use forward-slashes
83
-
84
- ### Features
85
-
86
- * better parallelization ([4d90537](https://github.com/FRSource/frs-replace/commit/4d905375f0550a097d9464b742d13515e1314c94)), closes [#17](https://github.com/FRSource/frs-replace/issues/17) [#10](https://github.com/FRSource/frs-replace/issues/10) [#19](https://github.com/FRSource/frs-replace/issues/19)
87
-
88
-
89
- ### Bug Fixes
90
-
91
- * **package:** update fast-glob to version 3.1.0 ([#44](https://github.com/FRSource/frs-replace/issues/44)) ([735785d](https://github.com/FRSource/frs-replace/commit/735785dfdc99869096cd4c6a3be60fb8f796d54b))
92
- * **package:** update write to version 2.0.0 ([#36](https://github.com/FRSource/frs-replace/issues/36)) ([d0b7ffd](https://github.com/FRSource/frs-replace/commit/d0b7ffdbbd668262860e130551e64b54840ac782))
93
- * **package:** update yargs to version 14.2.0 ([#45](https://github.com/FRSource/frs-replace/issues/45)) ([6df29e4](https://github.com/FRSource/frs-replace/commit/6df29e4e9bda262f9467d85349cd1c61d260c328)), closes [#35](https://github.com/FRSource/frs-replace/issues/35)
94
-
95
- ## [1.0.1](https://github.com/FRSource/frs-replace/compare/v1.0.0...v1.0.1) (2019-10-18)
96
-
97
-
98
- ### Bug Fixes
99
-
100
- * **package:** update yargs to version 13.2.2 ([749b721](https://github.com/FRSource/frs-replace/commit/749b72144049d9c900b04dd2b14473938af963d7)), closes [#20](https://github.com/FRSource/frs-replace/issues/20)
101
-
102
-
103
-
104
- <a name="1.0.0"></a>
105
- # [1.0.0](https://github.com/FRSource/frs-replace/compare/v0.1.2...v1.0.0) (2018-11-14)
106
-
107
-
108
- ### Features
109
-
110
- * **input:** add support for globbing matching ([#14](https://github.com/FRSource/frs-replace/issues/14)) ([b289ffe](https://github.com/FRSource/frs-replace/commit/b289ffe)), closes [#3](https://github.com/FRSource/frs-replace/issues/3)
111
- * **sync:** Sync speed improvements ([#18](https://github.com/FRSource/frs-replace/issues/18)) ([4ff2a1e](https://github.com/FRSource/frs-replace/commit/4ff2a1e)), closes [#17](https://github.com/FRSource/frs-replace/issues/17)
112
-
113
-
114
- ### BREAKING CHANGES
115
-
116
- * **input:** api options rename: 'inputOptions' to 'inputReadOptions', 'outputOptions' to 'outputWriteOptions'
117
- * **input:** cli options rename: 'in-opts' to 'i-read-opts', 'out-opts' to 'o-write-opts'
118
- Add possibility to set input or output options through cli
119
- Docs - fixes & new example
120
- Turn off camel-case-expansion to speed up yargs a bit
121
-
122
-
123
-
124
- <a name="0.1.2"></a>
125
- ## [0.1.2](https://github.com/FRSource/frs-replace/compare/v0.1.1...v0.1.2) (2018-10-19)
126
-
127
-
128
-
129
- <a name="0.1.1"></a>
130
- ## [0.1.1](https://github.com/FRSource/frs-replace/compare/v0.1.0...v0.1.1) (2018-10-17)
131
-
132
-
133
-
134
- <a name="0.1.0"></a>
135
- # [0.1.0](https://github.com/FRSource/frs-replace/compare/v0.0.6...v0.1.0) (2018-10-17)
136
-
137
-
138
- ### Features
139
-
140
- * **cli:** Input & output options ([06e8363](https://github.com/FRSource/frs-replace/commit/06e8363)), closes [#7](https://github.com/FRSource/frs-replace/issues/7)
141
-
142
-
143
-
144
- <a name="0.0.6"></a>
145
- ## [0.0.6](https://github.com/FRSource/frs-replace/compare/v0.0.5...v0.0.6) (2018-10-15)
146
-
147
-
148
- ### Bug Fixes
149
-
150
- * **docs:** positionals table ([7168474](https://github.com/FRSource/frs-replace/commit/7168474)), closes [#6](https://github.com/FRSource/frs-replace/issues/6)
151
-
152
-
153
-
154
- <a name="0.0.5"></a>
155
- ## [0.0.5](https://github.com/FRSource/frs-replace/compare/v0.0.4...v0.0.5) (2018-10-15)
156
-
157
-
158
- ### Bug Fixes
159
-
160
- * **docs:** styling & API usage/examples ([cba85dc](https://github.com/FRSource/frs-replace/commit/cba85dc)), closes [#1](https://github.com/FRSource/frs-replace/issues/1)
161
- * **node:** expose public node API ([c727dff](https://github.com/FRSource/frs-replace/commit/c727dff)), closes [#5](https://github.com/FRSource/frs-replace/issues/5)
162
-
163
-
164
-
165
- <a name="0.0.4"></a>
166
- ## [0.0.4](https://github.com/FRSource/frs-replace/compare/v0.0.3...v0.0.4) (2018-10-15)
167
-
168
-
169
-
170
- <a name="0.0.3"></a>
171
- ## [0.0.3](https://github.com/FRSource/frs-replace/compare/v0.0.2...v0.0.3) (2018-10-15)
172
-
173
-
174
-
175
- <a name="0.0.2"></a>
176
- ## [0.0.2](https://github.com/FRSource/frs-replace/compare/v0.0.1...v0.0.2) (2018-10-15)
177
-
178
-
179
- ### Bug Fixes
180
-
181
- * **npm:** lowercase package name to meet npm requirements ([06daa6a](https://github.com/FRSource/frs-replace/commit/06daa6a))
182
-
183
-
184
-
185
- <a name="0.0.1"></a>
186
- ## 0.0.1 (2018-10-15)
package/async.js DELETED
@@ -1 +0,0 @@
1
- module.exports = require('./src/sync')