@digigov/cli-build 2.0.0-07ee8440 → 2.0.0-0b806366

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/copy-files.js CHANGED
@@ -1,7 +1,6 @@
1
- import { logger, resolveProject } from "@digigov/cli/lib";
2
- import fs from "fs-extra";
3
- import path from "path";
4
- import glob from "globby";
1
+ import { logger, resolveProject } from '@digigov/cli/lib';
2
+ import fs from 'fs-extra';
3
+ import path from 'path';
5
4
 
6
5
  const packagePath = process.cwd();
7
6
  const project = resolveProject();
@@ -19,69 +18,34 @@ function includeFileInBuild(file) {
19
18
  logger.debug(`Copied ${sourcePath} to build directory`);
20
19
  }
21
20
 
22
- function copyRegistryFilesToSrc() {
23
- const registryPath = path.resolve(buildPath, "registry/index.js");
24
- const lazyPath = path.resolve(buildPath, "lazy/index.js");
25
- if (!fs.existsSync(registryPath) || !fs.existsSync(lazyPath)) return;
26
-
27
- const srcPath = path.resolve(buildPath, "src");
28
- logger.debug(`Copying registry and lazy files to ${srcPath}`);
29
- fs.copySync(registryPath, path.resolve(srcPath, "registry.js"));
30
- fs.copySync(lazyPath, path.resolve(srcPath, "lazy.js"));
31
- }
32
-
33
21
  /**
34
22
  * Create a package.json file in the build directory
35
23
  */
36
24
  function createRootPackageFile() {
37
25
  const packageData = fs.readFileSync(
38
- path.resolve(packagePath, "./package.json"),
39
- "utf8",
26
+ path.resolve(packagePath, './package.json'),
27
+ 'utf8'
40
28
  );
29
+
30
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
41
31
  const { nyc, scripts, devDependencies, workspaces, ...packageDataOther } =
42
32
  JSON.parse(packageData);
43
33
  const newPackageData = {
44
34
  ...packageDataOther,
45
35
  private: false,
46
- main: "./cjs/index.js",
47
- module: "./index.js",
48
- typings: "./index.d.ts",
36
+ exports: undefined,
37
+ main: 'index.js',
38
+ module: 'index.js',
39
+ type: 'module', // ESM only
49
40
  };
50
- const targetPath = path.resolve(buildPath, "./package.json");
41
+ const targetPath = path.resolve(buildPath, './package.json');
51
42
 
52
- fs.writeFileSync(targetPath, JSON.stringify(newPackageData, null, 2), "utf8");
43
+ fs.writeFileSync(targetPath, JSON.stringify(newPackageData, null, 2), 'utf8');
53
44
  logger.debug(`Created package.json in build directory`);
54
45
 
55
46
  return newPackageData;
56
47
  }
57
48
 
58
- /**
59
- * Create nested package.json files in the build directory
60
- *
61
- */
62
- function createNestedPackageFiles() {
63
- const indexPaths = glob.sync(path.join(buildPath, "**/index.js"), {
64
- ignore: [path.join(buildPath, "cjs/**")],
65
- });
66
-
67
- indexPaths.forEach((indexPath) => {
68
- if (indexPath === path.join(buildPath, "index.js")) return;
69
- const packageData = {
70
- sideEffects: false,
71
- module: "./index.js",
72
- types: "./index.d.ts",
73
- main: path.relative(
74
- path.dirname(indexPath),
75
- indexPath.replace(buildPath, path.join(buildPath, "/cjs")),
76
- ),
77
- };
78
- fs.writeFileSync(
79
- path.join(path.dirname(indexPath), "package.json"),
80
- JSON.stringify(packageData, null, 2),
81
- );
82
- });
83
- }
84
-
85
49
  /**
86
50
  * Prepend a string to a file
87
51
  *
@@ -89,8 +53,8 @@ function createNestedPackageFiles() {
89
53
  * @param {string} string - The string to prepend
90
54
  */
91
55
  function prepend(file, string) {
92
- const data = fs.readFileSync(file, "utf8");
93
- fs.writeFileSync(file, string + data, "utf8");
56
+ const data = fs.readFileSync(file, 'utf8');
57
+ fs.writeFileSync(file, string + data, 'utf8');
94
58
  logger.debug(`Prepended license to ${file}`);
95
59
  }
96
60
 
@@ -100,21 +64,21 @@ function prepend(file, string) {
100
64
  * @param {object} packageData - The package data
101
65
  */
102
66
  function addLicense(packageData) {
103
- const license = `/** @license Digigov v${packageData["version"]}
67
+ const license = `/** @license Digigov v${packageData['version']}
104
68
  *
105
69
  * This source code is licensed under the BSD-2-Clause license found in the
106
70
  * LICENSE file in the root directory of this source tree.
107
71
  */
108
72
  `;
109
- ["./index.js", "./index.mjs"].map(async (file) => {
73
+ ['./index.js', './index.mjs'].map(async (file) => {
110
74
  try {
111
75
  prepend(path.resolve(buildPath, file), license);
112
76
  } catch (err) {
113
77
  if (
114
- typeof err === "object" &&
78
+ typeof err === 'object' &&
115
79
  err &&
116
- "code" in err &&
117
- err.code === "ENOENT"
80
+ 'code' in err &&
81
+ err.code === 'ENOENT'
118
82
  ) {
119
83
  logger.debug(`Skipped license for ${file}`);
120
84
  } else {
@@ -124,36 +88,19 @@ function addLicense(packageData) {
124
88
  });
125
89
  }
126
90
 
127
- /**
128
- * Create separate index modules for each directory
129
- */
130
- function createSeparateIndexModules() {
131
- const files = glob.sync(path.join(buildPath, "**/*.js"), {
132
- ignore: [path.join(buildPath, "**/index.js")],
133
- });
134
-
135
- files.forEach((file) => {
136
- fs.mkdirSync(file.replace(/\.js$/, ""));
137
- fs.renameSync(file, file.replace(/\.js$/, "/index.js"));
138
- });
139
- }
140
-
141
91
  /**
142
92
  * Run the copy files script
143
93
  */
144
94
  export default function run() {
145
95
  const packageData = createRootPackageFile();
146
- createSeparateIndexModules();
147
- createNestedPackageFiles();
148
- copyRegistryFilesToSrc();
149
96
 
150
97
  [
151
98
  // use enhanced readme from workspace root for `@digigov/ui`
152
99
  // packageData.name === '@digigov/ui' ? '../../README.md' : './README.md',
153
- "./src",
154
- "./README.md",
155
- "./CHANGELOG.md",
156
- "../../LICENSE",
157
- ].map((file) => includeFileInBuild(file)),
158
- addLicense(packageData);
100
+ './src',
101
+ './README.md',
102
+ './CHANGELOG.md',
103
+ '../../LICENSE',
104
+ ].map((file) => includeFileInBuild(file));
105
+ addLicense(packageData);
159
106
  }
@@ -0,0 +1,3 @@
1
+ import config from '@digigov/cli-lint/eslint.config';
2
+
3
+ export default [...config];
@@ -1,86 +1,40 @@
1
- import { logger } from "@digigov/cli/lib";
2
- import path from "path";
3
- import fs from "fs-extra";
4
- import { SyntaxKind, Project as TsMorphProject } from "ts-morph";
5
- import assert from "assert";
6
-
7
- import { getProjectTsconfig } from "./common.js";
8
-
9
- /**
10
- * Generate registry files for the given project
11
- *
12
- * @param {object} project - The project object
13
- * @param {string} project.root - The project root directory
14
- * @param {string} project.distDir - The project build directory
15
- * @param {string} project.name - The project name as in package.json
16
- * @param {string[]} filePaths - The paths of the files to include in the registry
17
- * @param {boolean} shouldGenerateStoriesRegistry - Whether to export stories in the registry
18
- * @returns {Promise<[string, string]>} - The paths of the generated registry files
19
- */
20
- export async function generateRegistryFiles(
21
- project,
22
- filePaths,
23
- shouldGenerateStoriesRegistry = false,
24
- ) {
25
- const registryPath = ensureRegistryPath(project, "registry.js");
26
- const lazyRegistryPath = ensureRegistryPath(project, "lazy.js");
27
-
28
- const registry = generateRegistryFileContent(
29
- project,
30
- filePaths,
31
- shouldGenerateStoriesRegistry,
32
- );
33
-
34
- const componentPathsOnly = filePaths.filter(
35
- (path) => !path.includes("stories"),
36
- );
37
- const lazyRegistry = generateLazyFileContent(project, componentPathsOnly);
38
-
39
- await Promise.all([
40
- fs.writeFile(registryPath, registry),
41
- fs.writeFile(lazyRegistryPath, lazyRegistry),
42
- ]);
43
-
44
- return [registryPath, lazyRegistryPath];
45
- }
46
-
47
- /**
48
- * Ensure that the registry file does not already exist at the given path
49
- *
50
- * @param {object} project - The project object
51
- * @param {string} project.root - The project root directory
52
- * @param {string} project.distDir - The project build directory
53
- * @param {string} fileName - The name of the registry file
1
+ import { logger } from '@digigov/cli/lib';
2
+ import path from 'path';
3
+ import fs from 'fs-extra';
4
+ import { SyntaxKind, Project as TsMorphProject } from 'ts-morph';
5
+ import assert from 'assert';
6
+
7
+ import { getProjectTsconfig } from './common.js';
8
+
9
+ /** @typedef {Object} Project - Represents the project to be built
10
+ * @property {string} root - The project root directory
11
+ * @property {string} name - The project name as in package.json
12
+ * @property {string} src - The project src directory
13
+ * @property {string} distDir - The project build directory
54
14
  */
55
- function ensureRegistryPath(project, fileName) {
56
- const registryPath = path.join(project.root, project.distDir, fileName);
57
- if (fs.existsSync(registryPath))
58
- throw new Error(`A "${fileName}" file already exists at ${registryPath}.`);
59
- return registryPath;
60
- }
61
15
 
62
16
  /**
63
- * Generate registry file content for the given files
17
+ * Generate registry file for the given project
64
18
  *
65
- * @param {object} project - The project object
66
- * @param {string} project.root - The project root directory
67
- * @param {string} project.name - The project name as in package.json
19
+ * @param {Project} project - The project object
20
+ * @param {string} [registryFilename="registry.js"] - The name of the registry file
68
21
  * @param {string[]} absoluteFilePaths - The absolute paths of the files to include in the registry
69
- * @param {boolean} includeStories - Whether to include stories in the registry
70
- * @returns {string} - The registry file content or null if no components are found
22
+ * @returns {Promise<string>} - The path to the generated registry file
71
23
  */
72
- export function generateRegistryFileContent(
24
+ export async function generateRegistry(
73
25
  project,
74
26
  absoluteFilePaths,
75
- includeStories = false,
27
+ registryFilename = 'registry.js'
76
28
  ) {
29
+ const registryPath = ensureRegistryPath(project, registryFilename);
30
+
77
31
  const relativePaths = absoluteFilePaths.map((path) => {
78
32
  assert(
79
33
  path.startsWith(project.root),
80
- "Expected path to be in project root",
34
+ 'Expected path to be in project root'
81
35
  );
82
36
  return toNodeResolvablePath(
83
- path.replace(`${project.root}/src/`, `${project.name}/`),
37
+ path.replace(`${project.root}/src/`, `${project.name}/`)
84
38
  );
85
39
  });
86
40
  let registryPaths = relativePaths.map((path) => ({
@@ -90,25 +44,22 @@ export function generateRegistryFileContent(
90
44
 
91
45
  if (registryPaths.length === 0)
92
46
  throw new Error(
93
- "Could not generate registry. No exportable modules found.",
47
+ 'Could not generate registry. No exportable modules found.'
94
48
  );
95
49
 
96
50
  const importStatements = registryPaths.map(
97
- (file) => `import * as ${file.uid} from "${file.path}";`,
51
+ (file) => `import * as ${file.uid} from "${file.path}";`
98
52
  );
99
- const exportStatements = registryPaths.map(
100
- (file) => ` '${file.path}': lazyImport(${file.uid})`,
53
+ const componentsToExport = registryPaths.map(
54
+ (file) => ` '${file.path}': lazyImport(${file.uid})`
101
55
  );
102
56
 
103
- const [components, stories] = splitStoriesExports(exportStatements);
104
- logger.debug(`Including ${components.length} component modules in registry`);
105
-
106
- if (includeStories) {
107
- logger.debug(`Including ${stories.length} stories in registry`);
108
- }
57
+ logger.debug(
58
+ `Including ${componentsToExport.length} items in ${registryPath}`
59
+ );
109
60
 
110
- let out = `
111
- ${importStatements.join("\n")}
61
+ let registryFileContent = `
62
+ ${importStatements.join('\n')}
112
63
  function lazyImport(pkgImport) {
113
64
  return new Proxy(
114
65
  {},
@@ -128,73 +79,29 @@ function lazyImport(pkgImport) {
128
79
  )
129
80
  }
130
81
  export default {
131
- ${components.join(",\n")}
132
- };
133
- `;
134
-
135
- if (includeStories) {
136
- out += `
137
-
138
- export const stories = {
139
- ${stories.join(",\n")}
82
+ ${componentsToExport.join(',\n')}
140
83
  };
141
84
  `;
142
- }
143
- return out;
144
- }
145
-
146
- /**
147
- * Extract a node-resolvable path
148
- *
149
- * @param {string} inputPath - The file path
150
- * @returns {string} - The node-resolvable path
151
- */
152
- export function toNodeResolvablePath(inputPath) {
153
- const dir = path.dirname(inputPath);
154
- const base = path.basename(inputPath, path.extname(inputPath));
155
-
156
- return base === "index" ? dir : path.join(dir, base);
157
- }
158
-
159
- /**
160
- * Create a UID from a path
161
- *
162
- * @param {string} inputPath - The path
163
- * @returns {string} - The UID
164
- */
165
- export function createUid(inputPath) {
166
- return inputPath.replace(/[\/@\-.]/g, "_");
167
- }
85
+ await fs.writeFile(registryPath, registryFileContent);
168
86
 
169
- /**
170
- * Split the given files into components and stories
171
- *
172
- * @param {string[]} exportStatements - The export statements
173
- * @returns {[string[], string[]]} - The split components and stories exports
174
- */
175
- export function splitStoriesExports(exportStatements) {
176
- const stories = [];
177
- const components = [];
178
- for (const exportStatement of exportStatements) {
179
- if (exportStatement.includes("_stories")) {
180
- stories.push(exportStatement);
181
- } else {
182
- components.push(exportStatement);
183
- }
184
- }
185
- return [components, stories];
87
+ return registryPath;
186
88
  }
187
89
 
188
90
  /**
189
- * Generate lazy component registry file content for the given project
91
+ * Generate a lazy registry file for the given project
190
92
  *
191
- * @param {object} project - The project object
192
- * @param {string} project.root - The project root directory
193
- * @param {string} project.name - The project name as in package.json
93
+ * @param {Project} project - The project object
194
94
  * @param {string[]} filePaths - The files whose exports will be included in the lazy registry
195
- * @returns {string} - The lazy component registry file content or null if no components are found
95
+ * @param {string} [lazyFilename="lazy.js"] - The name of the registry file
96
+ * @returns {Promise<string>} - The path to the generated lazy registry file
196
97
  */
197
- export function generateLazyFileContent(project, filePaths) {
98
+ export async function generateLazyRegistry(
99
+ project,
100
+ filePaths,
101
+ lazyFilename = 'lazy.js'
102
+ ) {
103
+ const lazyPath = ensureRegistryPath(project, lazyFilename);
104
+
198
105
  const tsMorphProject = new TsMorphProject({
199
106
  tsConfigFilePath: getProjectTsconfig(project.root),
200
107
  });
@@ -211,15 +118,15 @@ export function generateLazyFileContent(project, filePaths) {
211
118
 
212
119
  for (const exportedComponent of exports) {
213
120
  if (
214
- exportedComponent !== "default" &&
215
- exportedComponent.match(/^[A-Z]/)
121
+ exportedComponent !== 'default' &&
122
+ exportedComponent.match(/^[A-Z][a-z]+/)
216
123
  ) {
217
124
  if (
218
125
  !allComponents[exportedComponent] ||
219
126
  allComponents[exportedComponent].length < filePath.length // Make import path more specific
220
127
  ) {
221
128
  allComponents[exportedComponent] = toNodeResolvablePath(
222
- filePath.replace(`${project.root}/src/`, `${project.name}/`),
129
+ filePath.replace(`${project.root}/src/`, `${project.name}/`)
223
130
  );
224
131
  }
225
132
  }
@@ -230,23 +137,63 @@ export function generateLazyFileContent(project, filePaths) {
230
137
 
231
138
  if (componentCount === 0)
232
139
  throw new Error(
233
- "Could not generate lazy registry. No exportable components found.",
140
+ 'Could not generate lazy registry. No exportable components found.'
234
141
  );
235
142
 
236
- logger.debug(`Including ${componentCount} components in lazy registry`);
143
+ logger.debug(`Including ${componentCount} components in ${lazyPath}`);
237
144
 
238
- const content = Object.entries(allComponents)
145
+ const componentsToExport = Object.entries(allComponents)
239
146
  .map(
240
147
  ([component, filePath]) =>
241
- ` '${component}': lazy(() => import('${filePath}').then((module) => ({ default: module['${component}'] })))`,
148
+ ` '${component}': lazy(() => import('${filePath}').then((module) => ({ default: module['${component}'] })))`
242
149
  )
243
- .join(",\n");
150
+ .join(',\n');
244
151
 
245
- return `import { lazy } from 'react';
152
+ const lazyFileContent = `import { lazy } from 'react';
246
153
  export default {
247
- ${content}
154
+ ${componentsToExport}
248
155
  };
249
156
  `;
157
+
158
+ await fs.writeFile(lazyPath, lazyFileContent);
159
+
160
+ return lazyPath;
161
+ }
162
+
163
+ /**
164
+ * Ensure that the registry file does not already exist at the given path
165
+ *
166
+ * @param {Project} project - The project object
167
+ * @param {string} fileName - The name of the registry file
168
+ */
169
+ function ensureRegistryPath(project, fileName) {
170
+ const registryPath = path.join(project.root, project.src, fileName);
171
+ if (fs.existsSync(registryPath))
172
+ throw new Error(`A "${fileName}" file already exists at ${registryPath}.`);
173
+ return registryPath;
174
+ }
175
+
176
+ /**
177
+ * Extract a node-resolvable path
178
+ *
179
+ * @param {string} inputPath - The file path
180
+ * @returns {string} - The node-resolvable path
181
+ */
182
+ function toNodeResolvablePath(inputPath) {
183
+ const dir = path.dirname(inputPath);
184
+ const base = path.basename(inputPath, path.extname(inputPath));
185
+
186
+ return base === 'index' ? dir : path.join(dir, base);
187
+ }
188
+
189
+ /**
190
+ * Create a UID from a path
191
+ *
192
+ * @param {string} inputPath - The path
193
+ * @returns {string} - The UID
194
+ */
195
+ function createUid(inputPath) {
196
+ return inputPath.replace(/[/@\-.]/g, '_');
250
197
  }
251
198
 
252
199
  /**