@modkit-org/aksel-icons-vue 1.0.0 → 1.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/src/generate.mjs CHANGED
@@ -1,103 +1,103 @@
1
- import { mkdir } from "node:fs/promises";
2
- import path from "node:path";
3
- import { fileURLToPath } from "node:url";
4
- import { safeCleanup } from "./lib/cleanup.mjs";
5
- import { getGeneratorConfig, getHelpText } from "./lib/config.mjs";
6
- import { getIconDirectories } from "./lib/icon-package.mjs";
7
- import {
8
- error as logError,
9
- headline,
10
- info,
11
- setQuiet,
12
- setVerbose,
13
- success,
14
- warn,
15
- } from "./lib/logger.mjs";
16
- import { readMetadata, writeMetadata } from "./lib/metadata.mjs";
17
- import { getGeneratorPaths } from "./lib/paths.mjs";
18
- import { collectSvgFilesByRoot } from "./lib/svg-discovery.mjs";
19
- import { generateVueFiles, writeIndexFile } from "./lib/vue-writer.mjs";
20
-
21
- const __filename = fileURLToPath(import.meta.url);
22
- const __dirname = path.dirname(__filename);
23
-
24
- let config;
25
- try {
26
- config = getGeneratorConfig(process.argv.slice(2));
27
- } catch (err) {
28
- const message = err instanceof Error ? err.message : String(err);
29
- logError(message);
30
- process.exit(1);
31
- }
32
-
33
- const { help, version, downloadUrl, tempDirectory, verbose, quiet } = config;
34
-
35
- if (help) {
36
- console.log(getHelpText());
37
- process.exit(0);
38
- }
39
-
40
- setQuiet(quiet);
41
- setVerbose(verbose && !quiet);
42
-
43
- const workspaceRoot = __dirname;
44
- const { metaFilePath, tempDirectoryAbsolute, typesRootPath } =
45
- getGeneratorPaths(workspaceRoot, tempDirectory);
46
-
47
- main().catch(async (err) => {
48
- const message = err instanceof Error ? err.message : String(err);
49
- logError(`Generation failed: ${message}`);
50
- await safeCleanup(tempDirectoryAbsolute);
51
- process.exit(1);
52
- });
53
-
54
- async function main() {
55
- headline("Aksel Icons Vue Generator");
56
- if (verbose && !quiet) {
57
- info("Verbose logging enabled.");
58
- }
59
-
60
- const existingMeta = await readMetadata(metaFilePath);
61
-
62
- if (existingMeta?.version === version) {
63
- success(
64
- `Icons are already up to date (version: ${version}). No action needed.`,
65
- );
66
- process.exit(0);
67
- }
68
-
69
- if (existingMeta?.version) {
70
- warn(`Updating icons from version ${existingMeta.version} to ${version}`);
71
- } else {
72
- info(
73
- "No existing metadata.json found. Generating icons for the first time.",
74
- );
75
- }
76
-
77
- info("Starting icon generation process...");
78
- await mkdir(tempDirectoryAbsolute, { recursive: true });
79
-
80
- info(`Latest icon version: ${version}`);
81
- const extractedDirectories = await getIconDirectories(
82
- downloadUrl,
83
- tempDirectoryAbsolute,
84
- );
85
-
86
- const groupedSvgFiles = await collectSvgFilesByRoot(extractedDirectories);
87
- const exports = await generateVueFiles({
88
- groupedSvgFiles,
89
- typesRootPath,
90
- version,
91
- downloadUrl,
92
- });
93
-
94
- await writeIndexFile(typesRootPath, exports, version, downloadUrl);
95
- success("Done writing index.ts");
96
-
97
- await writeMetadata(metaFilePath, version);
98
- success("Done writing metadata.json");
99
-
100
- await safeCleanup(tempDirectoryAbsolute, true);
101
- success("Generation completed successfully.");
102
- process.exit(0);
103
- }
1
+ import { mkdir } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import { safeCleanup } from "./lib/cleanup.mjs";
5
+ import { getGeneratorConfig, getHelpText } from "./lib/config.mjs";
6
+ import { getIconDirectories } from "./lib/icon-package.mjs";
7
+ import {
8
+ error as logError,
9
+ headline,
10
+ info,
11
+ setQuiet,
12
+ setVerbose,
13
+ success,
14
+ warn,
15
+ } from "./lib/logger.mjs";
16
+ import { readMetadata, writeMetadata } from "./lib/metadata.mjs";
17
+ import { getGeneratorPaths } from "./lib/paths.mjs";
18
+ import { collectSvgFilesByRoot } from "./lib/svg-discovery.mjs";
19
+ import { generateVueFiles, writeIndexFile } from "./lib/vue-writer.mjs";
20
+
21
+ const __filename = fileURLToPath(import.meta.url);
22
+ const __dirname = path.dirname(__filename);
23
+
24
+ let config;
25
+ try {
26
+ config = getGeneratorConfig(process.argv.slice(2));
27
+ } catch (err) {
28
+ const message = err instanceof Error ? err.message : String(err);
29
+ logError(message);
30
+ process.exit(1);
31
+ }
32
+
33
+ const { help, version, downloadUrl, tempDirectory, verbose, quiet } = config;
34
+
35
+ if (help) {
36
+ console.log(getHelpText());
37
+ process.exit(0);
38
+ }
39
+
40
+ setQuiet(quiet);
41
+ setVerbose(verbose && !quiet);
42
+
43
+ const workspaceRoot = __dirname;
44
+ const { metaFilePath, tempDirectoryAbsolute, typesRootPath } =
45
+ getGeneratorPaths(workspaceRoot, tempDirectory);
46
+
47
+ main().catch(async (err) => {
48
+ const message = err instanceof Error ? err.message : String(err);
49
+ logError(`Generation failed: ${message}`);
50
+ await safeCleanup(tempDirectoryAbsolute);
51
+ process.exit(1);
52
+ });
53
+
54
+ async function main() {
55
+ headline("Aksel Icons Vue Generator");
56
+ if (verbose && !quiet) {
57
+ info("Verbose logging enabled.");
58
+ }
59
+
60
+ const existingMeta = await readMetadata(metaFilePath);
61
+
62
+ if (existingMeta?.version === version) {
63
+ success(
64
+ `Icons are already up to date (version: ${version}). No action needed.`,
65
+ );
66
+ process.exit(0);
67
+ }
68
+
69
+ if (existingMeta?.version) {
70
+ warn(`Updating icons from version ${existingMeta.version} to ${version}`);
71
+ } else {
72
+ info(
73
+ "No existing metadata.json found. Generating icons for the first time.",
74
+ );
75
+ }
76
+
77
+ info("Starting icon generation process...");
78
+ await mkdir(tempDirectoryAbsolute, { recursive: true });
79
+
80
+ info(`Latest icon version: ${version}`);
81
+ const extractedDirectories = await getIconDirectories(
82
+ downloadUrl,
83
+ tempDirectoryAbsolute,
84
+ );
85
+
86
+ const groupedSvgFiles = await collectSvgFilesByRoot(extractedDirectories);
87
+ const exports = await generateVueFiles({
88
+ groupedSvgFiles,
89
+ typesRootPath,
90
+ version,
91
+ downloadUrl,
92
+ });
93
+
94
+ await writeIndexFile(typesRootPath, exports, version, downloadUrl);
95
+ success("Done writing index.ts");
96
+
97
+ await writeMetadata(metaFilePath, version);
98
+ success("Done writing metadata.json");
99
+
100
+ await safeCleanup(tempDirectoryAbsolute, true);
101
+ success("Generation completed successfully.");
102
+ process.exit(0);
103
+ }
@@ -1,18 +1,18 @@
1
- import { rm } from "node:fs/promises";
2
- import { pathExists } from "./fs-utils.mjs";
3
- import { step } from "./logger.mjs";
4
-
5
- export async function safeCleanup(directoryPath, printMessage = false) {
6
- try {
7
- const exists = await pathExists(directoryPath);
8
- if (exists && printMessage) {
9
- step("Cleaning up temporary files...");
10
- }
11
-
12
- if (exists) {
13
- await rm(directoryPath, { recursive: true, force: true });
14
- }
15
- } catch {
16
- // Ignore cleanup errors to preserve original script behavior.
17
- }
18
- }
1
+ import { rm } from "node:fs/promises";
2
+ import { pathExists } from "./fs-utils.mjs";
3
+ import { step } from "./logger.mjs";
4
+
5
+ export async function safeCleanup(directoryPath, printMessage = false) {
6
+ try {
7
+ const exists = await pathExists(directoryPath);
8
+ if (exists && printMessage) {
9
+ step("Cleaning up temporary files...");
10
+ }
11
+
12
+ if (exists) {
13
+ await rm(directoryPath, { recursive: true, force: true });
14
+ }
15
+ } catch {
16
+ // Ignore cleanup errors to preserve original script behavior.
17
+ }
18
+ }
@@ -1,105 +1,105 @@
1
- export const DEFAULT_DOWNLOAD_URL =
2
- "https://cdn.nav.no/aksel/icons/zip/aksel-icons.zip";
3
-
4
- export function getHelpText() {
5
- return [
6
- "Aksel Icons Vue Generator",
7
- "",
8
- "Usage:",
9
- " yarn generate-icons --version <value> [options]",
10
- "",
11
- "Required:",
12
- " --version, -v <value> Version to store in metadata and generated headers",
13
- "",
14
- "Options:",
15
- ` --download-url, -d <url> Icon zip URL (default: ${DEFAULT_DOWNLOAD_URL})`,
16
- " --temp-directory, -t <path> Temporary working directory (default: ./temp-icons)",
17
- " --verbose Show detailed per-directory progress",
18
- " --quiet, -q Show warnings/errors only",
19
- " --help, -h Show this help",
20
- ].join("\n");
21
- }
22
-
23
- export function parseArgs(argv) {
24
- const parsed = {};
25
-
26
- for (let index = 0; index < argv.length; index += 1) {
27
- const token = argv[index];
28
- if (!token.startsWith("-")) {
29
- continue;
30
- }
31
-
32
- const normalized = token.replace(/^-+/, "");
33
- const next = argv[index + 1];
34
- if (!next || next.startsWith("-")) {
35
- parsed[normalized] = "true";
36
- continue;
37
- }
38
-
39
- parsed[normalized] = next;
40
- index += 1;
41
- }
42
-
43
- return parsed;
44
- }
45
-
46
- export function getGeneratorConfig(argv) {
47
- const args = parseArgs(argv);
48
-
49
- const help = parseBooleanFlag(args.help ?? args.h ?? false);
50
-
51
- if (help) {
52
- return {
53
- help: true,
54
- version: "",
55
- downloadUrl: DEFAULT_DOWNLOAD_URL,
56
- tempDirectory: "./temp-icons",
57
- verbose: false,
58
- quiet: false,
59
- };
60
- }
61
-
62
- const version = args.version ?? args.v ?? "";
63
- const downloadUrl = args["download-url"] ?? args.d ?? DEFAULT_DOWNLOAD_URL;
64
- const tempDirectory = args["temp-directory"] ?? args.t ?? "./temp-icons";
65
- const verbose = parseBooleanFlag(args.verbose ?? false);
66
- const quiet = parseBooleanFlag(args.quiet ?? args.q ?? false);
67
-
68
- if (!version || version === "true") {
69
- throw new Error("'version' parameter is required.");
70
- }
71
-
72
- if (!downloadUrl) {
73
- throw new Error("'downloadUrl' parameter is required.");
74
- }
75
-
76
- return {
77
- help: false,
78
- version,
79
- downloadUrl,
80
- tempDirectory,
81
- verbose,
82
- quiet,
83
- };
84
- }
85
-
86
- function parseBooleanFlag(value) {
87
- if (typeof value === "boolean") {
88
- return value;
89
- }
90
-
91
- const normalized = String(value).trim().toLowerCase();
92
- if (!normalized) {
93
- return false;
94
- }
95
-
96
- if (["1", "true", "yes", "on"].includes(normalized)) {
97
- return true;
98
- }
99
-
100
- if (["0", "false", "no", "off"].includes(normalized)) {
101
- return false;
102
- }
103
-
104
- return true;
105
- }
1
+ export const DEFAULT_DOWNLOAD_URL =
2
+ "https://cdn.nav.no/aksel/icons/zip/aksel-icons.zip";
3
+
4
+ export function getHelpText() {
5
+ return [
6
+ "Aksel Icons Vue Generator",
7
+ "",
8
+ "Usage:",
9
+ " yarn generate-icons --version <value> [options]",
10
+ "",
11
+ "Required:",
12
+ " --version, -v <value> Version to store in metadata and generated headers",
13
+ "",
14
+ "Options:",
15
+ ` --download-url, -d <url> Icon zip URL (default: ${DEFAULT_DOWNLOAD_URL})`,
16
+ " --temp-directory, -t <path> Temporary working directory (default: ./temp-icons)",
17
+ " --verbose Show detailed per-directory progress",
18
+ " --quiet, -q Show warnings/errors only",
19
+ " --help, -h Show this help",
20
+ ].join("\n");
21
+ }
22
+
23
+ export function parseArgs(argv) {
24
+ const parsed = {};
25
+
26
+ for (let index = 0; index < argv.length; index += 1) {
27
+ const token = argv[index];
28
+ if (!token.startsWith("-")) {
29
+ continue;
30
+ }
31
+
32
+ const normalized = token.replace(/^-+/, "");
33
+ const next = argv[index + 1];
34
+ if (!next || next.startsWith("-")) {
35
+ parsed[normalized] = "true";
36
+ continue;
37
+ }
38
+
39
+ parsed[normalized] = next;
40
+ index += 1;
41
+ }
42
+
43
+ return parsed;
44
+ }
45
+
46
+ export function getGeneratorConfig(argv) {
47
+ const args = parseArgs(argv);
48
+
49
+ const help = parseBooleanFlag(args.help ?? args.h ?? false);
50
+
51
+ if (help) {
52
+ return {
53
+ help: true,
54
+ version: "",
55
+ downloadUrl: DEFAULT_DOWNLOAD_URL,
56
+ tempDirectory: "./temp-icons",
57
+ verbose: false,
58
+ quiet: false,
59
+ };
60
+ }
61
+
62
+ const version = args.version ?? args.v ?? "";
63
+ const downloadUrl = args["download-url"] ?? args.d ?? DEFAULT_DOWNLOAD_URL;
64
+ const tempDirectory = args["temp-directory"] ?? args.t ?? "./temp-icons";
65
+ const verbose = parseBooleanFlag(args.verbose ?? false);
66
+ const quiet = parseBooleanFlag(args.quiet ?? args.q ?? false);
67
+
68
+ if (!version || version === "true") {
69
+ throw new Error("'version' parameter is required.");
70
+ }
71
+
72
+ if (!downloadUrl) {
73
+ throw new Error("'downloadUrl' parameter is required.");
74
+ }
75
+
76
+ return {
77
+ help: false,
78
+ version,
79
+ downloadUrl,
80
+ tempDirectory,
81
+ verbose,
82
+ quiet,
83
+ };
84
+ }
85
+
86
+ function parseBooleanFlag(value) {
87
+ if (typeof value === "boolean") {
88
+ return value;
89
+ }
90
+
91
+ const normalized = String(value).trim().toLowerCase();
92
+ if (!normalized) {
93
+ return false;
94
+ }
95
+
96
+ if (["1", "true", "yes", "on"].includes(normalized)) {
97
+ return true;
98
+ }
99
+
100
+ if (["0", "false", "no", "off"].includes(normalized)) {
101
+ return false;
102
+ }
103
+
104
+ return true;
105
+ }
@@ -1,10 +1,10 @@
1
- import { stat } from "node:fs/promises";
2
-
3
- export async function pathExists(targetPath) {
4
- try {
5
- await stat(targetPath);
6
- return true;
7
- } catch {
8
- return false;
9
- }
10
- }
1
+ import { stat } from "node:fs/promises";
2
+
3
+ export async function pathExists(targetPath) {
4
+ try {
5
+ await stat(targetPath);
6
+ return true;
7
+ } catch {
8
+ return false;
9
+ }
10
+ }
@@ -1,59 +1,59 @@
1
- import extract from "extract-zip";
2
- import { createWriteStream } from "node:fs";
3
- import { readdir } from "node:fs/promises";
4
- import path from "node:path";
5
- import { pipeline } from "node:stream/promises";
6
- import { info, step } from "./logger.mjs";
7
-
8
- export async function getIconDirectories(url, destinationPath) {
9
- const zipFilePath = path.join(destinationPath, "icons.zip");
10
-
11
- info(`Downloading icon package from: ${url}`);
12
- const response = await fetch(url);
13
- if (!response.ok || !response.body) {
14
- throw new Error(
15
- `Failed to download icons from ${url}. HTTP ${response.status}`,
16
- );
17
- }
18
-
19
- await pipeline(response.body, createWriteStream(zipFilePath));
20
-
21
- step("Extracting icon package...");
22
- await extract(zipFilePath, { dir: destinationPath });
23
-
24
- const candidates = await readdir(destinationPath, { withFileTypes: true });
25
- const extractedDirectories = [];
26
- for (const candidate of candidates) {
27
- if (!candidate.isDirectory()) {
28
- continue;
29
- }
30
-
31
- const directoryPath = path.join(destinationPath, candidate.name);
32
- if (await directoryContainsSvg(directoryPath)) {
33
- extractedDirectories.push(directoryPath);
34
- }
35
- }
36
-
37
- if (extractedDirectories.length === 0) {
38
- throw new Error("Could not find extracted Icon directories");
39
- }
40
-
41
- return extractedDirectories;
42
- }
43
-
44
- async function directoryContainsSvg(directoryPath) {
45
- const entries = await readdir(directoryPath, { withFileTypes: true });
46
-
47
- for (const entry of entries) {
48
- const fullPath = path.join(directoryPath, entry.name);
49
- if (entry.isFile() && entry.name.toLowerCase().endsWith(".svg")) {
50
- return true;
51
- }
52
-
53
- if (entry.isDirectory() && (await directoryContainsSvg(fullPath))) {
54
- return true;
55
- }
56
- }
57
-
58
- return false;
59
- }
1
+ import extract from "extract-zip";
2
+ import { createWriteStream } from "node:fs";
3
+ import { readdir } from "node:fs/promises";
4
+ import path from "node:path";
5
+ import { pipeline } from "node:stream/promises";
6
+ import { info, step } from "./logger.mjs";
7
+
8
+ export async function getIconDirectories(url, destinationPath) {
9
+ const zipFilePath = path.join(destinationPath, "icons.zip");
10
+
11
+ info(`Downloading icon package from: ${url}`);
12
+ const response = await fetch(url);
13
+ if (!response.ok || !response.body) {
14
+ throw new Error(
15
+ `Failed to download icons from ${url}. HTTP ${response.status}`,
16
+ );
17
+ }
18
+
19
+ await pipeline(response.body, createWriteStream(zipFilePath));
20
+
21
+ step("Extracting icon package...");
22
+ await extract(zipFilePath, { dir: destinationPath });
23
+
24
+ const candidates = await readdir(destinationPath, { withFileTypes: true });
25
+ const extractedDirectories = [];
26
+ for (const candidate of candidates) {
27
+ if (!candidate.isDirectory()) {
28
+ continue;
29
+ }
30
+
31
+ const directoryPath = path.join(destinationPath, candidate.name);
32
+ if (await directoryContainsSvg(directoryPath)) {
33
+ extractedDirectories.push(directoryPath);
34
+ }
35
+ }
36
+
37
+ if (extractedDirectories.length === 0) {
38
+ throw new Error("Could not find extracted Icon directories");
39
+ }
40
+
41
+ return extractedDirectories;
42
+ }
43
+
44
+ async function directoryContainsSvg(directoryPath) {
45
+ const entries = await readdir(directoryPath, { withFileTypes: true });
46
+
47
+ for (const entry of entries) {
48
+ const fullPath = path.join(directoryPath, entry.name);
49
+ if (entry.isFile() && entry.name.toLowerCase().endsWith(".svg")) {
50
+ return true;
51
+ }
52
+
53
+ if (entry.isDirectory() && (await directoryContainsSvg(fullPath))) {
54
+ return true;
55
+ }
56
+ }
57
+
58
+ return false;
59
+ }
@@ -1,23 +1,23 @@
1
- export function convertToValidIdentifier(label) {
2
- let result = "";
3
- let capitalize = true;
4
-
5
- for (const char of label) {
6
- if (/^[a-zA-Z0-9]$/.test(char)) {
7
- if (capitalize) {
8
- result += char.toUpperCase();
9
- capitalize = false;
10
- } else {
11
- result += char;
12
- }
13
- } else {
14
- capitalize = true;
15
- }
16
- }
17
-
18
- if (/^\d/.test(result)) {
19
- return `Number${result}`;
20
- }
21
-
22
- return result;
23
- }
1
+ export function convertToValidIdentifier(label) {
2
+ let result = "";
3
+ let capitalize = true;
4
+
5
+ for (const char of label) {
6
+ if (/^[a-zA-Z0-9]$/.test(char)) {
7
+ if (capitalize) {
8
+ result += char.toUpperCase();
9
+ capitalize = false;
10
+ } else {
11
+ result += char;
12
+ }
13
+ } else {
14
+ capitalize = true;
15
+ }
16
+ }
17
+
18
+ if (/^\d/.test(result)) {
19
+ return `Number${result}`;
20
+ }
21
+
22
+ return result;
23
+ }