presetter 3.0.0 → 3.0.1

Sign up to get free protection for your applications and to get access to all the features.
package/lib/preset.js CHANGED
@@ -166,10 +166,10 @@ async function getScripts(context) {
166
166
  async function setupPreset(...uris) {
167
167
  // NOTE: comparing packages before and after installation is the only reliable way
168
168
  // to extract the name of the preset in case it's given as a git url or file path etc.
169
- const context = await getContext();
170
169
  const {
171
- root
172
- } = context.target;
170
+ path
171
+ } = await (0, _package.getPackage)();
172
+ const root = (0, _path.dirname)(path);
173
173
  const packageBefore = (await (0, _readPkg.default)({
174
174
  cwd: root
175
175
  })).devDependencies; // install presetter & the preset
@@ -195,7 +195,8 @@ async function setupPreset(...uris) {
195
195
  preset
196
196
  }); // bootstrap configuration files with the new .presetterrc.json
197
197
 
198
- await bootstrapContent(await getContext()); // insert post install script if not preset
198
+ const context = await getContext();
199
+ await bootstrapContent(context); // insert post install script if not preset
199
200
 
200
201
  await (0, _writePkg.default)(root, (0, _lodash.defaultsDeep)(context.target.package, {
201
202
  scripts: {
@@ -292,9 +293,16 @@ async function getDestinationMap(template, context) {
292
293
  const {
293
294
  custom: {
294
295
  noSymlinks
296
+ },
297
+ target: {
298
+ root
295
299
  }
296
- } = context;
297
- const outDir = (0, _path.resolve)(__dirname, '..', 'generated', context.target.name);
300
+ } = context; // make sure we use the path of presetter under the target project, not the one via npx
301
+
302
+ const presetterDir = (0, _resolvePkg.default)('presetter', {
303
+ cwd: root
304
+ });
305
+ const outDir = (0, _path.resolve)(presetterDir, 'generated', context.target.name);
298
306
  const relativePaths = [...Object.keys(template)];
299
307
  return Object.fromEntries([...relativePaths.map(relativePath => [relativePath, (0, _path.resolve)( // output on the project root if it's specified as not a symlink
300
308
  noSymlinks.includes(relativePath) ? context.target.root : outDir, relativePath)])]);
package/lib/preset.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../source/preset.ts"],"names":["PRESETTERRC","JSON_INDENT","getPresetterRC","root","potentialConfigFiles","map","ext","path","custom","assertPresetterRC","Error","updatePresetterRC","config","existingPresetterRC","catch","spaces","value","Array","isArray","getPresetAssets","context","preset","presets","assets","module","cwd","target","default","presetPresetAsset","asset","extensions","extends","extension","push","Promise","all","flat","getScripts","variable","scripts","filter","scriptsFromPreset","reduce","merged","scriptsWithCustomConfig","setupPreset","uris","getContext","packageBefore","devDependencies","join","add","saveAs","lockFile","packageAfter","newPackages","getNewPackages","name","bootstrapContent","package","prepare","bootstrapPreset","options","force","content","resolvedContext","filteredContent","ignores","destinationMap","getDestinationMap","unsetPreset","configurationLink","json","template","noSymlinks","outDir","__dirname","relativePaths","Object","keys","fromEntries","relativePath","includes","before","after"],"mappings":"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","sourcesContent":["/*\n * *** MIT LICENSE ***\n * -------------------------------------------------------------------------\n * This code may be modified and distributed under the MIT license.\n * See the LICENSE file for details.\n * -------------------------------------------------------------------------\n *\n * @summary Procedures for setting up a preset\n *\n * @author Alvis HT Tang <alvis@hilbert.space>\n * @license MIT\n * @copyright Copyright (c) 2020 - All Rights Reserved.\n * -------------------------------------------------------------------------\n */\n\nimport { info } from 'console';\nimport { pathExists, writeJSON } from 'fs-extra';\nimport { defaultsDeep } from 'lodash';\nimport { dirname, resolve } from 'path';\nimport readPackage from 'read-pkg';\nimport resolvePackage from 'resolve-pkg';\nimport writePackage from 'write-pkg';\n\nimport { generateContent, getVariable, resolveContext } from './content';\nimport { linkFiles, loadFile, unlinkFiles, writeFiles } from './io';\nimport {\n arePeerPackagesAutoInstalled,\n getPackage,\n reifyDependencies,\n} from './package';\nimport { filter, isJSON, merge, template } from './template';\n\nimport type {\n PresetAsset,\n PresetContext,\n PresetterConfig,\n ResolvedPresetContext,\n Template,\n} from './types';\n\n/** presetter configuration filename */\nconst PRESETTERRC = '.presetterrc';\n\nconst JSON_INDENT = 2;\n\n/**\n * get the .presetterrc configuration file content\n * @param root the base directory in which the configuration file should be located\n * @returns content of the configuration file\n */\nexport async function getPresetterRC(root: string): Promise<PresetterConfig> {\n const potentialConfigFiles = ['', '.json'].map((ext) =>\n resolve(root, `${PRESETTERRC}${ext}`),\n );\n\n for (const path of potentialConfigFiles) {\n if (await pathExists(path)) {\n // return the first customisation file found\n const custom = await loadFile(path, 'json');\n assertPresetterRC(custom);\n\n return custom;\n }\n }\n\n throw new Error('Missing preset defined in .presetterrc');\n}\n\n/**\n * update .presetterrc configuration file content\n * @param root the base directory in which the configuration file should be located\n * @param config content to be merged with the existing configuration file\n */\nexport async function updatePresetterRC(\n root: string,\n config: PresetterConfig,\n): Promise<void> {\n const existingPresetterRC = await getPresetterRC(root).catch(() => ({}));\n\n await writeJSON(\n resolve(root, `${PRESETTERRC}.json`),\n merge(existingPresetterRC, config),\n { spaces: JSON_INDENT },\n );\n}\n\n/**\n * check that the configuration is valid\n * @param value content from a configuration file\n */\nexport function assertPresetterRC(\n value: unknown,\n): asserts value is PresetterConfig {\n if (\n !isJSON(value) ||\n (typeof value['preset'] !== 'string' && !Array.isArray(value['preset']))\n ) {\n throw new Error(`invalid presetter configuration file`);\n }\n}\n\n/**\n * get the preset package name from package.json\n * @param context context about the target project and any customisation in .presetterrc\n * @returns name of the preset package\n */\nexport async function getPresetAssets(\n context: PresetContext,\n): Promise<PresetAsset[]> {\n // get the preset name\n const { preset } = context.custom;\n\n const presets = Array.isArray(preset) ? preset : [preset];\n\n const assets: PresetAsset[] = [];\n\n for (const preset of presets) {\n try {\n // get the preset\n const module = resolvePackage(preset, {\n cwd: context.target.root,\n });\n\n const { default: presetPresetAsset } = (await import(module!)) as {\n default: (args: PresetContext) => Promise<PresetAsset>;\n };\n\n const asset = await presetPresetAsset(context);\n\n // add extended assets first\n const extensions =\n asset.extends?.map(async (extension) =>\n getPresetAssets({\n ...context,\n custom: { ...context.custom, preset: extension },\n }),\n ) ?? [];\n assets.push(...(await Promise.all(extensions)).flat());\n\n // then asset from this preset so that this preset can override the extended ones\n assets.push(asset);\n } catch {\n throw new Error(`cannot resolve preset ${preset}`);\n }\n }\n\n return assets;\n}\n\n/**\n * merge all scripts templates\n * @param context context about the target project and any customisation in .presetterrc\n * @returns scripts template\n */\nexport async function getScripts(\n context: PresetContext,\n): Promise<Record<string, string>> {\n const { custom } = context;\n\n // get assets from all configured presets\n const assets = await getPresetAssets(context);\n\n // compute the final variable to be used in the scripts template\n const variable = getVariable(assets, context);\n\n // load templated scripts from presets\n const scripts = await Promise.all(\n assets\n .map((asset) => asset.scripts)\n .filter((path): path is string => typeof path === 'string')\n .map(\n async (path) =>\n (await loadFile(path, 'yaml')) as Record<string, string>,\n ),\n );\n\n // merge all template scripts from presets\n const scriptsFromPreset = scripts.reduce(\n (merged, scripts) => merge(merged, scripts),\n {},\n );\n\n // merge customised scripts with the preset scripts\n const scriptsWithCustomConfig = merge(scriptsFromPreset, custom.scripts);\n\n // replace the template variables\n return template(scriptsWithCustomConfig, variable);\n}\n\n/**\n * adopt a preset to the project\n * @param uris list of name or git url of the preset\n */\nexport async function setupPreset(...uris: string[]): Promise<void> {\n // NOTE: comparing packages before and after installation is the only reliable way\n // to extract the name of the preset in case it's given as a git url or file path etc.\n\n const context = await getContext();\n const { root } = context.target;\n const packageBefore = (await readPackage({ cwd: root })).devDependencies;\n\n // install presetter & the preset\n info(`Installing ${uris.join(' ')}... it may take a few moment...`);\n await reifyDependencies({\n root,\n add: ['presetter', ...uris],\n saveAs: 'dev',\n lockFile: true,\n });\n\n // extract the name of the installed preset\n const packageAfter = (await readPackage({ cwd: root })).devDependencies;\n const newPackages = getNewPackages({ ...packageBefore }, { ...packageAfter });\n const preset = newPackages.filter((name) => name !== 'presetter');\n\n info('Updating .presetterrc.json & package.json');\n // update .presetterrc.json\n await updatePresetterRC(root, { preset });\n\n // bootstrap configuration files with the new .presetterrc.json\n await bootstrapContent(await getContext());\n\n // insert post install script if not preset\n await writePackage(\n root,\n defaultsDeep(context.target.package, {\n scripts: { prepare: 'presetter bootstrap' },\n }),\n );\n\n info('Done. Enjoy coding!');\n}\n\n/**\n * bootstrap the preset to the current project root\n * @param options options on how to bootstrap the preset\n * @param options.force do all steps despite potential step saving\n */\nexport async function bootstrapPreset(options?: {\n force?: boolean;\n}): Promise<void> {\n const { force = false } = { ...options };\n\n const context = await getContext();\n\n // install all related packages first\n if (force || !arePeerPackagesAutoInstalled()) {\n await reifyDependencies({ root: context.target.root });\n }\n\n // generate configurations\n await bootstrapContent(context);\n}\n\n/**\n * generate files from templates and link them to the target project root\n * @param context context about the target project and any customisation in .presetterrc\n */\nexport async function bootstrapContent(context: PresetContext): Promise<void> {\n const assets = await getPresetAssets(context);\n const content = await generateContent(assets, context);\n const resolvedContext = await resolveContext(assets, context);\n const filteredContent = filter(content, ...(context.custom.ignores ?? []));\n\n const destinationMap = await getDestinationMap(\n filteredContent,\n resolvedContext,\n );\n\n await writeFiles(context.target.root, filteredContent, destinationMap);\n await linkFiles(context.target.root, destinationMap);\n}\n\n/**\n * uninstall the preset from the current project root\n */\nexport async function unsetPreset(): Promise<void> {\n const context = await getContext();\n const assets = await getPresetAssets(context);\n const content = await generateContent(assets, context);\n const resolvedContext = await resolveContext(assets, context);\n const configurationLink = await getDestinationMap(content, resolvedContext);\n\n await unlinkFiles(context.target.root, configurationLink);\n}\n\n/**\n * get context about the target project and any customisation in .presetterrc\n * @returns context about the target project and any customisation in .presetterrc\n */\nexport async function getContext(): Promise<PresetContext> {\n const { json, path } = await getPackage();\n const root = dirname(path);\n const target = { name: json.name, root, package: json };\n const custom = await getPresetterRC(root);\n\n return {\n target,\n custom,\n };\n}\n\n/**\n * compute the output paths of all configuration files to be generated\n * @param template resolved template map\n * @param context resolved context about the target project and customisation\n * @returns mapping of configuration symlinks to its real path\n */\nexport async function getDestinationMap(\n template: Record<string, Template>,\n context: ResolvedPresetContext<'noSymlinks'>,\n): Promise<Record<string, string>> {\n const {\n custom: { noSymlinks },\n } = context;\n const outDir = resolve(__dirname, '..', 'generated', context.target.name);\n\n const relativePaths = [...Object.keys(template)];\n\n return Object.fromEntries([\n ...relativePaths.map((relativePath): [string, string] => [\n relativePath,\n resolve(\n // output on the project root if it's specified as not a symlink\n noSymlinks.includes(relativePath) ? context.target.root : outDir,\n relativePath,\n ),\n ]),\n ]);\n}\n\n/**\n * get a list of new packages installed by comparing the before and after state of devDependencies in package.json\n * @param before before state of devDependencies in package.json\n * @param after after state of devDependencies in package.json\n * @returns list of new package names\n */\nfunction getNewPackages(\n before: Record<string, string>,\n after: Record<string, string>,\n): string[] {\n return Object.keys(after).filter((name): name is string => !before[name]);\n}\n"],"file":"preset.js"}
1
+ {"version":3,"sources":["../source/preset.ts"],"names":["PRESETTERRC","JSON_INDENT","getPresetterRC","root","potentialConfigFiles","map","ext","path","custom","assertPresetterRC","Error","updatePresetterRC","config","existingPresetterRC","catch","spaces","value","Array","isArray","getPresetAssets","context","preset","presets","assets","module","cwd","target","default","presetPresetAsset","asset","extensions","extends","extension","push","Promise","all","flat","getScripts","variable","scripts","filter","scriptsFromPreset","reduce","merged","scriptsWithCustomConfig","setupPreset","uris","packageBefore","devDependencies","join","add","saveAs","lockFile","packageAfter","newPackages","getNewPackages","name","getContext","bootstrapContent","package","prepare","bootstrapPreset","options","force","content","resolvedContext","filteredContent","ignores","destinationMap","getDestinationMap","unsetPreset","configurationLink","json","template","noSymlinks","presetterDir","outDir","relativePaths","Object","keys","fromEntries","relativePath","includes","before","after"],"mappings":"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","sourcesContent":["/*\n * *** MIT LICENSE ***\n * -------------------------------------------------------------------------\n * This code may be modified and distributed under the MIT license.\n * See the LICENSE file for details.\n * -------------------------------------------------------------------------\n *\n * @summary Procedures for setting up a preset\n *\n * @author Alvis HT Tang <alvis@hilbert.space>\n * @license MIT\n * @copyright Copyright (c) 2020 - All Rights Reserved.\n * -------------------------------------------------------------------------\n */\n\nimport { info } from 'console';\nimport { pathExists, writeJSON } from 'fs-extra';\nimport { defaultsDeep } from 'lodash';\nimport { dirname, resolve } from 'path';\nimport readPackage from 'read-pkg';\nimport resolvePackage from 'resolve-pkg';\nimport writePackage from 'write-pkg';\n\nimport { generateContent, getVariable, resolveContext } from './content';\nimport { linkFiles, loadFile, unlinkFiles, writeFiles } from './io';\nimport {\n arePeerPackagesAutoInstalled,\n getPackage,\n reifyDependencies,\n} from './package';\nimport { filter, isJSON, merge, template } from './template';\n\nimport type {\n PresetAsset,\n PresetContext,\n PresetterConfig,\n ResolvedPresetContext,\n Template,\n} from './types';\n\n/** presetter configuration filename */\nconst PRESETTERRC = '.presetterrc';\n\nconst JSON_INDENT = 2;\n\n/**\n * get the .presetterrc configuration file content\n * @param root the base directory in which the configuration file should be located\n * @returns content of the configuration file\n */\nexport async function getPresetterRC(root: string): Promise<PresetterConfig> {\n const potentialConfigFiles = ['', '.json'].map((ext) =>\n resolve(root, `${PRESETTERRC}${ext}`),\n );\n\n for (const path of potentialConfigFiles) {\n if (await pathExists(path)) {\n // return the first customisation file found\n const custom = await loadFile(path, 'json');\n assertPresetterRC(custom);\n\n return custom;\n }\n }\n\n throw new Error('Missing preset defined in .presetterrc');\n}\n\n/**\n * update .presetterrc configuration file content\n * @param root the base directory in which the configuration file should be located\n * @param config content to be merged with the existing configuration file\n */\nexport async function updatePresetterRC(\n root: string,\n config: PresetterConfig,\n): Promise<void> {\n const existingPresetterRC = await getPresetterRC(root).catch(() => ({}));\n\n await writeJSON(\n resolve(root, `${PRESETTERRC}.json`),\n merge(existingPresetterRC, config),\n { spaces: JSON_INDENT },\n );\n}\n\n/**\n * check that the configuration is valid\n * @param value content from a configuration file\n */\nexport function assertPresetterRC(\n value: unknown,\n): asserts value is PresetterConfig {\n if (\n !isJSON(value) ||\n (typeof value['preset'] !== 'string' && !Array.isArray(value['preset']))\n ) {\n throw new Error(`invalid presetter configuration file`);\n }\n}\n\n/**\n * get the preset package name from package.json\n * @param context context about the target project and any customisation in .presetterrc\n * @returns name of the preset package\n */\nexport async function getPresetAssets(\n context: PresetContext,\n): Promise<PresetAsset[]> {\n // get the preset name\n const { preset } = context.custom;\n\n const presets = Array.isArray(preset) ? preset : [preset];\n\n const assets: PresetAsset[] = [];\n\n for (const preset of presets) {\n try {\n // get the preset\n const module = resolvePackage(preset, {\n cwd: context.target.root,\n });\n\n const { default: presetPresetAsset } = (await import(module!)) as {\n default: (args: PresetContext) => Promise<PresetAsset>;\n };\n\n const asset = await presetPresetAsset(context);\n\n // add extended assets first\n const extensions =\n asset.extends?.map(async (extension) =>\n getPresetAssets({\n ...context,\n custom: { ...context.custom, preset: extension },\n }),\n ) ?? [];\n assets.push(...(await Promise.all(extensions)).flat());\n\n // then asset from this preset so that this preset can override the extended ones\n assets.push(asset);\n } catch {\n throw new Error(`cannot resolve preset ${preset}`);\n }\n }\n\n return assets;\n}\n\n/**\n * merge all scripts templates\n * @param context context about the target project and any customisation in .presetterrc\n * @returns scripts template\n */\nexport async function getScripts(\n context: PresetContext,\n): Promise<Record<string, string>> {\n const { custom } = context;\n\n // get assets from all configured presets\n const assets = await getPresetAssets(context);\n\n // compute the final variable to be used in the scripts template\n const variable = getVariable(assets, context);\n\n // load templated scripts from presets\n const scripts = await Promise.all(\n assets\n .map((asset) => asset.scripts)\n .filter((path): path is string => typeof path === 'string')\n .map(\n async (path) =>\n (await loadFile(path, 'yaml')) as Record<string, string>,\n ),\n );\n\n // merge all template scripts from presets\n const scriptsFromPreset = scripts.reduce(\n (merged, scripts) => merge(merged, scripts),\n {},\n );\n\n // merge customised scripts with the preset scripts\n const scriptsWithCustomConfig = merge(scriptsFromPreset, custom.scripts);\n\n // replace the template variables\n return template(scriptsWithCustomConfig, variable);\n}\n\n/**\n * adopt a preset to the project\n * @param uris list of name or git url of the preset\n */\nexport async function setupPreset(...uris: string[]): Promise<void> {\n // NOTE: comparing packages before and after installation is the only reliable way\n // to extract the name of the preset in case it's given as a git url or file path etc.\n const { path } = await getPackage();\n const root = dirname(path);\n const packageBefore = (await readPackage({ cwd: root })).devDependencies;\n\n // install presetter & the preset\n info(`Installing ${uris.join(' ')}... it may take a few moment...`);\n await reifyDependencies({\n root,\n add: ['presetter', ...uris],\n saveAs: 'dev',\n lockFile: true,\n });\n\n // extract the name of the installed preset\n const packageAfter = (await readPackage({ cwd: root })).devDependencies;\n const newPackages = getNewPackages({ ...packageBefore }, { ...packageAfter });\n const preset = newPackages.filter((name) => name !== 'presetter');\n\n info('Updating .presetterrc.json & package.json');\n // update .presetterrc.json\n await updatePresetterRC(root, { preset });\n\n // bootstrap configuration files with the new .presetterrc.json\n const context = await getContext();\n await bootstrapContent(context);\n\n // insert post install script if not preset\n await writePackage(\n root,\n defaultsDeep(context.target.package, {\n scripts: { prepare: 'presetter bootstrap' },\n }),\n );\n\n info('Done. Enjoy coding!');\n}\n\n/**\n * bootstrap the preset to the current project root\n * @param options options on how to bootstrap the preset\n * @param options.force do all steps despite potential step saving\n */\nexport async function bootstrapPreset(options?: {\n force?: boolean;\n}): Promise<void> {\n const { force = false } = { ...options };\n\n const context = await getContext();\n\n // install all related packages first\n if (force || !arePeerPackagesAutoInstalled()) {\n await reifyDependencies({ root: context.target.root });\n }\n\n // generate configurations\n await bootstrapContent(context);\n}\n\n/**\n * generate files from templates and link them to the target project root\n * @param context context about the target project and any customisation in .presetterrc\n */\nexport async function bootstrapContent(context: PresetContext): Promise<void> {\n const assets = await getPresetAssets(context);\n const content = await generateContent(assets, context);\n const resolvedContext = await resolveContext(assets, context);\n const filteredContent = filter(content, ...(context.custom.ignores ?? []));\n\n const destinationMap = await getDestinationMap(\n filteredContent,\n resolvedContext,\n );\n\n await writeFiles(context.target.root, filteredContent, destinationMap);\n await linkFiles(context.target.root, destinationMap);\n}\n\n/**\n * uninstall the preset from the current project root\n */\nexport async function unsetPreset(): Promise<void> {\n const context = await getContext();\n const assets = await getPresetAssets(context);\n const content = await generateContent(assets, context);\n const resolvedContext = await resolveContext(assets, context);\n const configurationLink = await getDestinationMap(content, resolvedContext);\n\n await unlinkFiles(context.target.root, configurationLink);\n}\n\n/**\n * get context about the target project and any customisation in .presetterrc\n * @returns context about the target project and any customisation in .presetterrc\n */\nexport async function getContext(): Promise<PresetContext> {\n const { json, path } = await getPackage();\n const root = dirname(path);\n const target = { name: json.name, root, package: json };\n const custom = await getPresetterRC(root);\n\n return {\n target,\n custom,\n };\n}\n\n/**\n * compute the output paths of all configuration files to be generated\n * @param template resolved template map\n * @param context resolved context about the target project and customisation\n * @returns mapping of configuration symlinks to its real path\n */\nexport async function getDestinationMap(\n template: Record<string, Template>,\n context: ResolvedPresetContext<'noSymlinks'>,\n): Promise<Record<string, string>> {\n const {\n custom: { noSymlinks },\n target: { root },\n } = context;\n // make sure we use the path of presetter under the target project, not the one via npx\n const presetterDir = resolvePackage('presetter', { cwd: root });\n const outDir = resolve(presetterDir!, 'generated', context.target.name);\n\n const relativePaths = [...Object.keys(template)];\n\n return Object.fromEntries([\n ...relativePaths.map((relativePath): [string, string] => [\n relativePath,\n resolve(\n // output on the project root if it's specified as not a symlink\n noSymlinks.includes(relativePath) ? context.target.root : outDir,\n relativePath,\n ),\n ]),\n ]);\n}\n\n/**\n * get a list of new packages installed by comparing the before and after state of devDependencies in package.json\n * @param before before state of devDependencies in package.json\n * @param after after state of devDependencies in package.json\n * @returns list of new package names\n */\nfunction getNewPackages(\n before: Record<string, string>,\n after: Record<string, string>,\n): string[] {\n return Object.keys(after).filter((name): name is string => !before[name]);\n}\n"],"file":"preset.js"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "presetter",
3
- "version": "3.0.0",
3
+ "version": "3.0.1",
4
4
  "engines": {
5
5
  "node": ">=12.10.0"
6
6
  },