presetter 3.0.0 → 3.0.1

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/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
  },