Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@codemod-utils/blueprints

Package Overview
Dependencies
Maintainers
1
Versions
13
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@codemod-utils/blueprints - npm Package Compare versions

Comparing version 1.0.0 to 1.1.0

59

dist/blueprints/decide-version.d.ts
type PackageName = string;
type PackageVersion = string;
type Options = {
/**
* Returns the version that can be installed for a package.
*
* Always favors the current version in the user's project (a no-op).
* Uses the latest version only if the project doesn't depend on the
* package yet.
*
* @param packageName
*
* Name of the package.
*
* @param options
*
* An object with `dependencies` (the current versions in the user's
* project) and `latestVersions` (the versions to install by default).
*
* @return
*
* The version to install.
*
* @example
*
* First, pass `latestVersions` to `decideVersion()`.
*
* ```ts
* const latestVersions = new Map([
* ['embroider-css-modules', '1.0.0'],
* ['webpack', '5.89.0'],
* ]);
*
* // Create a wrapper
* function getVersion(packageName, options) {
* const { dependencies } = options;
*
* return decideVersion(packageName, {
* dependencies,
* latestVersions,
* });
* }
* ```
*
* Then, pass `dependencies` to `decideVersion()`.
*
* ```ts
* const options = {
* dependencies: new Map([
* ['webpack', '^5.82.0'],
* ]),
* };
*
* getVersion('embroider-css-modules', options); // '^1.0.0'
* getVersion('webpack', options); // '^5.82.0' (no-op)
* ```
*/
export declare function decideVersion(packageName: PackageName, options: {
dependencies: Map<PackageName, PackageVersion>;
latestVersions: Map<PackageName, PackageVersion>;
};
export declare function decideVersion(packageName: PackageName, options: Options): PackageVersion;
}): PackageVersion;
export {};

@@ -0,1 +1,55 @@

/**
* Returns the version that can be installed for a package.
*
* Always favors the current version in the user's project (a no-op).
* Uses the latest version only if the project doesn't depend on the
* package yet.
*
* @param packageName
*
* Name of the package.
*
* @param options
*
* An object with `dependencies` (the current versions in the user's
* project) and `latestVersions` (the versions to install by default).
*
* @return
*
* The version to install.
*
* @example
*
* First, pass `latestVersions` to `decideVersion()`.
*
* ```ts
* const latestVersions = new Map([
* ['embroider-css-modules', '1.0.0'],
* ['webpack', '5.89.0'],
* ]);
*
* // Create a wrapper
* function getVersion(packageName, options) {
* const { dependencies } = options;
*
* return decideVersion(packageName, {
* dependencies,
* latestVersions,
* });
* }
* ```
*
* Then, pass `dependencies` to `decideVersion()`.
*
* ```ts
* const options = {
* dependencies: new Map([
* ['webpack', '^5.82.0'],
* ]),
* };
*
* getVersion('embroider-css-modules', options); // '^1.0.0'
* getVersion('webpack', options); // '^5.82.0' (no-op)
* ```
*/
export function decideVersion(packageName, options) {

@@ -2,0 +56,0 @@ const { dependencies, latestVersions } = options;

@@ -0,1 +1,43 @@

/**
* Returns where `npx` installs the codemod on the user's machine.
*
* @param fileURL
*
* Pass the value of `import.meta.url`.
*
* @return
*
* The installation path.
*
* @example
*
* To read blueprint files, get the path to the `blueprints` folder.
*
* ```ts
* // src/utils/blueprints/blueprints-root.ts
* import { join } from 'node:path';
*
* const fileURL = import.meta.url;
*
* const blueprintsRoot = join(getFilePath(fileURL), '../../blueprints');
*
* // '<some/absolute/path>/src/blueprints'
* ```
*
* Afterwards, prepend the file path with `blueprintsRoot`.
*
* ```ts
* import { readFileSync } from 'node:fs';
* import { join } from 'node:path';
*
* const blueprintFilePaths = ['LICENSE.md', 'README.md'];
*
* blueprintFilePaths.forEach((blueprintFilePath) => {
* const blueprintFile = readFileSync(
* join(blueprintsRoot, blueprintFilePath),
* 'utf8',
* );
* });
* ```
*/
export declare function getFilePath(fileURL: string): string;
import { dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
/**
* Returns where `npx` installs the codemod on the user's machine.
*
* @param fileURL
*
* Pass the value of `import.meta.url`.
*
* @return
*
* The installation path.
*
* @example
*
* To read blueprint files, get the path to the `blueprints` folder.
*
* ```ts
* // src/utils/blueprints/blueprints-root.ts
* import { join } from 'node:path';
*
* const fileURL = import.meta.url;
*
* const blueprintsRoot = join(getFilePath(fileURL), '../../blueprints');
*
* // '<some/absolute/path>/src/blueprints'
* ```
*
* Afterwards, prepend the file path with `blueprintsRoot`.
*
* ```ts
* import { readFileSync } from 'node:fs';
* import { join } from 'node:path';
*
* const blueprintFilePaths = ['LICENSE.md', 'README.md'];
*
* blueprintFilePaths.forEach((blueprintFilePath) => {
* const blueprintFile = readFileSync(
* join(blueprintsRoot, blueprintFilePath),
* 'utf8',
* );
* });
* ```
*/
export function getFilePath(fileURL) {

@@ -4,0 +46,0 @@ const __filename = fileURLToPath(fileURL);

@@ -0,1 +1,73 @@

/**
* Returns the blueprint file after filling it out with data.
*
* @param file
*
* A blueprint file, which may contain escape, evaluate, and
* interpolate delimiters.
*
* - Escape (`<%- %>`) - escape an HTML code
* - Evaluate (`<% %>`) - evaluate a JavaScript code
* - Interpolate (`<%= %>`) - substitute a value
*
* @param data
*
* An object that provides the data needed for the file.
*
* @return
*
* The processed blueprint file.
*
* @example
*
* First, create a blueprint file.
*
* ```ts
* // blueprints/__testAppLocation__/ember-cli-build.js
* 'use strict';
*
* const EmberApp = require('ember-cli/lib/broccoli/ember-app');
*
* module.exports = function (defaults) {
* const app = new EmberApp(defaults, {
* // Add options here
* autoImport: {
* watchDependencies: ['<%= addon.name %>'],
* },<% if (testApp.hasTypeScript) { %>
* 'ember-cli-babel': {
* enableTypeScriptTransform: true,
* },<% } %>
* });
*
* const { maybeEmbroider } = require('@embroider/test-setup');
*
* return maybeEmbroider(app);
* };
* ```
*
* Then, pass data to the file.
*
* ```ts
* import { readFileSync } from 'node:fs';
* import { join } from 'node:path';
*
* // Read file
* const blueprintFilePath = '__testAppLocation__/ember-cli-build.js';
*
* const blueprintFile = readFileSync(
* join(blueprintsRoot, blueprintFilePath),
* 'utf8',
* );
*
* // Process file
* processTemplate(blueprintFile, {
* addon: {
* name: 'ember-container-query',
* },
* app: {
* hasTypeScript: true,
* },
* });
* ```
*/
export declare function processTemplate(file: string, data?: object): string;
import template from 'lodash.template';
/**
* Returns the blueprint file after filling it out with data.
*
* @param file
*
* A blueprint file, which may contain escape, evaluate, and
* interpolate delimiters.
*
* - Escape (`<%- %>`) - escape an HTML code
* - Evaluate (`<% %>`) - evaluate a JavaScript code
* - Interpolate (`<%= %>`) - substitute a value
*
* @param data
*
* An object that provides the data needed for the file.
*
* @return
*
* The processed blueprint file.
*
* @example
*
* First, create a blueprint file.
*
* ```ts
* // blueprints/__testAppLocation__/ember-cli-build.js
* 'use strict';
*
* const EmberApp = require('ember-cli/lib/broccoli/ember-app');
*
* module.exports = function (defaults) {
* const app = new EmberApp(defaults, {
* // Add options here
* autoImport: {
* watchDependencies: ['<%= addon.name %>'],
* },<% if (testApp.hasTypeScript) { %>
* 'ember-cli-babel': {
* enableTypeScriptTransform: true,
* },<% } %>
* });
*
* const { maybeEmbroider } = require('@embroider/test-setup');
*
* return maybeEmbroider(app);
* };
* ```
*
* Then, pass data to the file.
*
* ```ts
* import { readFileSync } from 'node:fs';
* import { join } from 'node:path';
*
* // Read file
* const blueprintFilePath = '__testAppLocation__/ember-cli-build.js';
*
* const blueprintFile = readFileSync(
* join(blueprintsRoot, blueprintFilePath),
* 'utf8',
* );
*
* // Process file
* processTemplate(blueprintFile, {
* addon: {
* name: 'ember-container-query',
* },
* app: {
* hasTypeScript: true,
* },
* });
* ```
*/
export function processTemplate(file, data) {

@@ -3,0 +75,0 @@ const settings = {

16

package.json
{
"name": "@codemod-utils/blueprints",
"version": "1.0.0",
"version": "1.1.0",
"description": "Utilities for blueprints",

@@ -43,12 +43,12 @@ "keywords": [

"@sondr3/minitest": "^0.1.2",
"@types/lodash.template": "^4.5.1",
"@types/node": "^18.17.15",
"concurrently": "^8.2.1",
"eslint": "^8.49.0",
"@types/lodash.template": "^4.5.2",
"@types/node": "^18.18.7",
"concurrently": "^8.2.2",
"eslint": "^8.52.0",
"prettier": "^3.0.3",
"typescript": "^5.2.2",
"@codemod-utils/tests": "1.0.0",
"@shared-configs/typescript": "0.0.0",
"@shared-configs/prettier": "0.0.0",
"@shared-configs/typescript": "0.0.0",
"@shared-configs/eslint-config-node": "0.0.0"
"@shared-configs/eslint-config-node": "0.0.0",
"@codemod-utils/tests": "1.1.1"
},

@@ -55,0 +55,0 @@ "engines": {

@@ -17,8 +17,11 @@ [![This project uses GitHub Actions for continuous integration.](https://github.com/ijlee2/codemod-utils/actions/workflows/ci.yml/badge.svg)](https://github.com/ijlee2/codemod-utils/actions/workflows/ci.yml)

Need to add or update a dependency? You can use `decideVersion` to know which version to install.
Returns the version that can be installed for a package.
It is assumed that:
Always favors the current version in the user's project (a no-op). Uses the latest version only if the project doesn't depend on the package yet.
- You don't want to rely on a library such as [`latest-version`](https://www.npmjs.com/package/latest-version). (The reasons are, your codemod would have an extra dependency and your tests may fail without stubs—more dependencies.)
- Before calling `decideVersion`, the codemod has computed `dependencies` (current dependencies of the user's project) and stored `latestVersions` (versions to install by default) somewhere.
> [!NOTE]
> It is assumed that:
>
> - You don't want to rely on a library such as [`latest-version`](https://www.npmjs.com/package/latest-version). (The reasons are, your codemod would have an extra dependency and your tests may fail without stubs—more dependencies.)
> - Before calling `decideVersion`, the codemod has computed `dependencies` (current dependencies of the user's project) and stored `latestVersions` (versions to install by default) somewhere.

@@ -29,15 +32,14 @@ <details>

Step 1. Pass `latestVersions` to `decideVersion`.
First, pass `latestVersions` to `decideVersion()`.
```js
```ts
import { decideVersion } from '@codemod-utils/blueprints';
// Hardcode the versions
const latestVersions = new Map([
['embroider-css-modules', '0.1.2'],
['webpack', '5.82.0'],
['embroider-css-modules', '1.0.0'],
['webpack', '5.89.0'],
]);
// Create a wrapper
export function getVersion(packageName, options) {
function getVersion(packageName, options) {
const { dependencies } = options;

@@ -52,15 +54,13 @@

Step 2. Pass `dependencies` to `decideVersion`.
Then, pass `dependencies` to `decideVersion()`.
```js
// `dependencies` obtained from the user's `package.json`
```ts
const options = {
dependencies: new Map([
['webpack', '^5.79.0'],
['webpack', '^5.82.0'],
]),
};
// Query version
getVersion('embroider-css-modules', options); // '^0.1.2'
getVersion('webpack', options); // '^5.79.0' (no-op)
getVersion('embroider-css-modules', options); // '^1.0.0'
getVersion('webpack', options); // '^5.82.0' (no-op)
```

@@ -73,3 +73,3 @@

When a user runs your codemod with `npx`, where are your blueprint files installed? With `getFilePath`, you don't need to worry about the actual location.
Returns where `npx` installs the codemod on the user's machine.

@@ -80,5 +80,6 @@ <details>

Step 1. Pass `import.meta.url` to `getFilePath`. Append the relative path to your blueprints folder.
To read blueprint files, get the path to the `blueprints` folder.
```js
```ts
/* src/utils/blueprints/blueprints-root.ts */
import { join } from 'node:path';

@@ -90,19 +91,21 @@

// Create a wrapper
export const blueprintsRoot = join(getFilePath(fileURL), '../../blueprints');
const blueprintsRoot = join(getFilePath(fileURL), '../../blueprints');
// '<some/absolute/path>/src/blueprints'
```
Step 2. Prepend the file path with `blueprintsRoot`.
Afterwards, prepend the file path with `blueprintsRoot`.
```js
```ts
import { readFileSync } from 'node:fs';
import { join } from 'node:path';
// Read file
const blueprintFilePath = '__addonLocation__/rollup.config.mjs';
const blueprintFilePaths = ['LICENSE.md', 'README.md'];
const blueprintFile = readFileSync(
join(blueprintsRoot, blueprintFilePath),
'utf8',
);
blueprintFilePaths.forEach((blueprintFilePath) => {
const blueprintFile = readFileSync(
join(blueprintsRoot, blueprintFilePath),
'utf8',
);
});
```

@@ -115,3 +118,3 @@

Often, blueprints need context: When a condition is true, a file should be generated in a different way. You can [embed logic with delimiters](https://lodash.com/docs/#template) in the blueprint files, then use `processTemplate` to pass data.
Often, blueprints need context: If some condition is true, a file should be generated in a different way. You can [embed logic with delimiters](https://lodash.com/docs/#template) in the blueprint files, then use `processTemplate` to pass data.

@@ -128,33 +131,30 @@ There are 3 types of delimiters:

Step 1. Indicate how the file should be created.
First, create a blueprint file.
```js
/* blueprints/__addonLocation__/rollup.config.mjs */
<% if (options.packages.addon.hasTypeScript) { %>import typescript from 'rollup-plugin-ts';<% } else { %>import { babel } from '@rollup/plugin-babel';<% } %>
import copy from 'rollup-plugin-copy';
import { Addon } from '@embroider/addon-dev/rollup';
```ts
/* blueprints/__testAppLocation__/ember-cli-build.js */
'use strict';
const addon = new Addon({
srcDir: 'src',
destDir: 'dist',
});
const EmberApp = require('ember-cli/lib/broccoli/ember-app');
export default {
output: addon.output(),
module.exports = function (defaults) {
const app = new EmberApp(defaults, {
// Add options here
autoImport: {
watchDependencies: ['<%= addon.name %>'],
},<% if (testApp.hasTypeScript) { %>
'ember-cli-babel': {
enableTypeScriptTransform: true,
},<% } %>
});
plugins: [
addon.publicEntrypoints([<%= context.addon.publicEntrypoints.map((filePath) => `'${filePath}'`).join(', ') %>]),
const { maybeEmbroider } = require('@embroider/test-setup');
addon.appReexports([<%= context.addon.appReexports.map((filePath) => `'${filePath}'`).join(', ') %>]),
addon.dependencies(),
// ...
],
return maybeEmbroider(app);
};
```
Step 2. Pass data to the file.
Then, pass data to the file.
```js
```ts
import { readFileSync } from 'node:fs';

@@ -166,3 +166,3 @@ import { join } from 'node:path';

// Read file
const blueprintFilePath = '__addonLocation__/rollup.config.mjs';
const blueprintFilePath = '__testAppLocation__/ember-cli-build.js';

@@ -176,4 +176,8 @@ const blueprintFile = readFileSync(

processTemplate(blueprintFile, {
context, // context = { addon: ... }
options, // options = { packages: ... }
addon: {
name: 'ember-container-query',
},
app: {
hasTypeScript: true,
},
});

@@ -180,0 +184,0 @@ ```

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc