@cyberskill/shared 3.4.0 → 3.5.0
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/dist/config/graphql-codegen/graphql-codegen.type.d.ts +1 -1
- package/dist/config/storybook/storybook.preview.js +8 -15
- package/dist/config/storybook/storybook.preview.js.map +1 -1
- package/dist/config/vitest/vitest.unit.js.map +1 -1
- package/dist/constant/index.js +2 -2
- package/dist/constant/response-status.d.ts +254 -0
- package/dist/constant/response-status.js +65 -1
- package/dist/constant/response-status.js.map +1 -1
- package/dist/node/cli/index.js +10 -9
- package/dist/node/cli/index.js.map +1 -1
- package/dist/node/command/command.util.js +32 -20
- package/dist/node/command/command.util.js.map +1 -1
- package/dist/node/express/express.type.d.ts +2 -0
- package/dist/node/express/express.util.js +11 -4
- package/dist/node/express/express.util.js.map +1 -1
- package/dist/node/log/log.type.d.ts +1 -5
- package/dist/node/log/log.type.js.map +1 -1
- package/dist/node/log/log.util.d.ts +2 -4
- package/dist/node/log/log.util.js +38 -40
- package/dist/node/log/log.util.js.map +1 -1
- package/dist/node/mongo/mongo.controller.d.ts +3 -1
- package/dist/node/mongo/mongo.controller.mongoose.js +75 -78
- package/dist/node/mongo/mongo.controller.mongoose.js.map +1 -1
- package/dist/node/mongo/mongo.controller.native.d.ts +9 -1
- package/dist/node/mongo/mongo.controller.native.js +17 -14
- package/dist/node/mongo/mongo.controller.native.js.map +1 -1
- package/dist/node/mongo/mongo.controller.type.d.ts +76 -0
- package/dist/node/mongo/mongo.dynamic-populate.d.ts +2 -1
- package/dist/node/mongo/mongo.dynamic-populate.js +12 -12
- package/dist/node/mongo/mongo.dynamic-populate.js.map +1 -1
- package/dist/node/mongo/mongo.internal-types.d.ts +81 -0
- package/dist/node/mongo/mongo.internal-types.js +40 -0
- package/dist/node/mongo/mongo.internal-types.js.map +1 -0
- package/dist/node/mongo/mongo.populate.d.ts +2 -1
- package/dist/node/mongo/mongo.populate.js +130 -171
- package/dist/node/mongo/mongo.populate.js.map +1 -1
- package/dist/node/mongo/mongo.type.d.ts +1 -1
- package/dist/node/mongo/mongo.type.js.map +1 -1
- package/dist/node/mongo/mongo.util.d.ts +7 -7
- package/dist/node/mongo/mongo.util.js +34 -32
- package/dist/node/mongo/mongo.util.js.map +1 -1
- package/dist/node/path/path.constant.d.ts +3 -6
- package/dist/node/path/path.constant.js +31 -25
- package/dist/node/path/path.constant.js.map +1 -1
- package/dist/node/storage/index.js +2 -2
- package/dist/node/storage/storage.util.d.ts +6 -0
- package/dist/node/storage/storage.util.js +4 -1
- package/dist/node/storage/storage.util.js.map +1 -1
- package/dist/react/log/log.type.d.ts +1 -5
- package/dist/react/log/log.util.d.ts +2 -5
- package/dist/react/log/log.util.js +21 -25
- package/dist/react/log/log.util.js.map +1 -1
- package/dist/util/common/common.util.d.ts +8 -0
- package/dist/util/common/common.util.js +4 -1
- package/dist/util/common/common.util.js.map +1 -1
- package/dist/util/common/index.js +2 -2
- package/dist/util/index.d.ts +1 -0
- package/dist/util/index.js +7 -6
- package/dist/util/log/index.d.ts +2 -0
- package/dist/util/log/index.js +2 -0
- package/dist/util/log/log.type.d.ts +8 -0
- package/dist/util/log/log.util.d.ts +17 -0
- package/dist/util/log/log.util.js +14 -0
- package/dist/util/log/log.util.js.map +1 -0
- package/package.json +83 -40
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import { regexSearchMapper as e } from "../../util/common/common.util.js";
|
|
2
|
-
import {
|
|
3
|
-
import { validate as
|
|
4
|
-
import { addGitIgnoreEntry as
|
|
5
|
-
import { MIGRATE_MONGO_CONFIG as
|
|
2
|
+
import { getNestedValue as t, setNestedValue as n } from "../../util/object/object.util.js";
|
|
3
|
+
import { validate as r } from "../../util/validate/validate.util.js";
|
|
4
|
+
import { addGitIgnoreEntry as i, writeFileSync as a } from "../fs/fs.util.js";
|
|
5
|
+
import { MIGRATE_MONGO_CONFIG as o, PATH as s } from "../path/path.constant.js";
|
|
6
6
|
import "./mongo.populate.js";
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import { randomUUID as
|
|
7
|
+
import c from "mongoose-aggregate-paginate-v2";
|
|
8
|
+
import l from "mongoose-paginate-v2";
|
|
9
|
+
import { randomUUID as u } from "node:crypto";
|
|
10
10
|
//#region src/node/mongo/mongo.util.ts
|
|
11
|
-
function
|
|
11
|
+
function d(e) {
|
|
12
12
|
return e === e.toUpperCase() ? e.charAt(0).toUpperCase() + e.slice(1).toLowerCase() : e;
|
|
13
13
|
}
|
|
14
|
-
var
|
|
14
|
+
var f = {
|
|
15
15
|
createGenericFields() {
|
|
16
16
|
return {
|
|
17
|
-
id:
|
|
17
|
+
id: u(),
|
|
18
18
|
isDel: !1,
|
|
19
19
|
createdAt: /* @__PURE__ */ new Date(),
|
|
20
20
|
updatedAt: /* @__PURE__ */ new Date()
|
|
@@ -32,7 +32,7 @@ var p = {
|
|
|
32
32
|
return new e.Schema({
|
|
33
33
|
id: {
|
|
34
34
|
type: String,
|
|
35
|
-
default: () =>
|
|
35
|
+
default: () => u(),
|
|
36
36
|
unique: !0
|
|
37
37
|
},
|
|
38
38
|
isDel: {
|
|
@@ -47,7 +47,7 @@ var p = {
|
|
|
47
47
|
toObject: { virtuals: !0 }
|
|
48
48
|
});
|
|
49
49
|
return n.forEach(({ name: e, options: t, get: n }) => {
|
|
50
|
-
if (
|
|
50
|
+
if (f.isDynamicVirtual(t)) {
|
|
51
51
|
let r = i.statics;
|
|
52
52
|
r._dynamicVirtuals ||= [], r._dynamicVirtuals.push({
|
|
53
53
|
name: e,
|
|
@@ -59,24 +59,24 @@ var p = {
|
|
|
59
59
|
let r = i.virtual(e, t);
|
|
60
60
|
n && r.get(n);
|
|
61
61
|
}
|
|
62
|
-
}), r || i.add(
|
|
62
|
+
}), r || i.add(f.createGenericSchema(e)), i;
|
|
63
63
|
},
|
|
64
64
|
createModel({ mongoose: e, name: t, schema: n, virtuals: r = [], pagination: i = !0, aggregate: a = !0, middlewares: o = [] }) {
|
|
65
65
|
if (!t) throw Error("Model name is required.");
|
|
66
66
|
if (e.models[t]) return e.models[t];
|
|
67
|
-
let s =
|
|
67
|
+
let s = f.createSchema({
|
|
68
68
|
mongoose: e,
|
|
69
69
|
schema: n,
|
|
70
70
|
virtuals: r
|
|
71
71
|
});
|
|
72
|
-
(i || a) &&
|
|
73
|
-
let
|
|
74
|
-
return r.length > 0 && (
|
|
72
|
+
(i || a) && f.applyPlugins(s, [i && l, a && c]), f.applyMiddlewares(s, o);
|
|
73
|
+
let u = e.model(t, s);
|
|
74
|
+
return r.length > 0 && (u._virtualConfigs = r), u;
|
|
75
75
|
},
|
|
76
76
|
validator: {
|
|
77
77
|
isRequired() {
|
|
78
78
|
return async function(e) {
|
|
79
|
-
return !
|
|
79
|
+
return !r.isEmpty(e);
|
|
80
80
|
};
|
|
81
81
|
},
|
|
82
82
|
isUnique(e) {
|
|
@@ -99,38 +99,40 @@ var p = {
|
|
|
99
99
|
},
|
|
100
100
|
setConfig: (e) => {
|
|
101
101
|
let t = `// This file is automatically generated by the Cyberskill CLI.\nmodule.exports = ${JSON.stringify(e, null, 4)}`;
|
|
102
|
-
|
|
102
|
+
a(s.MIGRATE_MONGO_CONFIG, t), i(s.GIT_IGNORE, o);
|
|
103
103
|
}
|
|
104
104
|
},
|
|
105
|
-
regexify(
|
|
106
|
-
if (!
|
|
107
|
-
let
|
|
108
|
-
if (!
|
|
109
|
-
for (let
|
|
110
|
-
let i =
|
|
111
|
-
if (typeof
|
|
105
|
+
regexify(r, i) {
|
|
106
|
+
if (!r) return {};
|
|
107
|
+
let a = { ...r };
|
|
108
|
+
if (!i || i.length === 0) return a;
|
|
109
|
+
for (let r of i) {
|
|
110
|
+
let i = r.toString().split("."), o = t(a, i);
|
|
111
|
+
if (typeof o == "string" && o.length > 0 && o.length <= 200) {
|
|
112
112
|
let t = {
|
|
113
|
-
$regex: `.*${e(
|
|
113
|
+
$regex: `.*${e(o)}.*`,
|
|
114
114
|
$options: "i"
|
|
115
115
|
};
|
|
116
|
-
|
|
116
|
+
a = n(a, i, t);
|
|
117
117
|
}
|
|
118
118
|
}
|
|
119
|
-
return
|
|
119
|
+
return a;
|
|
120
120
|
},
|
|
121
121
|
isDynamicVirtual(e) {
|
|
122
122
|
return !!(e && typeof e.ref == "function");
|
|
123
123
|
},
|
|
124
124
|
async getNewRecords(e, t, n, r = {}) {
|
|
125
125
|
let i = await e.findAll(r);
|
|
126
|
-
|
|
126
|
+
if (!i.success) throw Error(`Failed to query existing records: ${i.message}`);
|
|
127
|
+
return t.filter((e) => !i.result.some((t) => n(t, e)));
|
|
127
128
|
},
|
|
128
129
|
async getExistingRecords(e, t, n, r = {}) {
|
|
129
130
|
let i = await e.findAll(r);
|
|
130
|
-
|
|
131
|
+
if (!i.success) throw Error(`Failed to query existing records: ${i.message}`);
|
|
132
|
+
return i.result.filter((e) => t.some((t) => n(e, t)));
|
|
131
133
|
}
|
|
132
134
|
};
|
|
133
135
|
//#endregion
|
|
134
|
-
export {
|
|
136
|
+
export { d as convertEnumToModelName, f as mongo };
|
|
135
137
|
|
|
136
138
|
//# sourceMappingURL=mongo.util.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mongo.util.js","names":[],"sources":["../../../src/node/mongo/mongo.util.ts"],"sourcesContent":["import type migrate from 'migrate-mongo';\nimport type mongooseRaw from 'mongoose';\n\nimport aggregatePaginate from 'mongoose-aggregate-paginate-v2';\nimport mongoosePaginate from 'mongoose-paginate-v2';\nimport { randomUUID } from 'node:crypto';\n\nimport { deepClone, getNestedValue, regexSearchMapper, setNestedValue } from '#util/index.js';\nimport { validate } from '#util/validate/index.js';\n\nimport type { MongoController } from './mongo.controller.js';\nimport type { C_Document, I_CreateModelOptions, I_CreateSchemaOptions, I_DynamicVirtualConfig, I_DynamicVirtualOptions, I_ExtendedModel, I_GenericDocument, I_MongooseModelMiddleware, T_MongoosePlugin, T_MongooseShema, T_QueryFilter, T_VirtualOptions, T_WithId } from './mongo.type.js';\n\nimport { addGitIgnoreEntry, writeFileSync } from '../fs/index.js';\nimport { MIGRATE_MONGO_CONFIG, PATH } from '../path/index.js';\n\n/**\n * Converts enum values to proper model names.\n * Handles common naming conventions like converting 'USER' to 'User'.\n *\n * @param enumValue - The enum value to convert\n * @returns The converted model name\n */\nexport function convertEnumToModelName(enumValue: string): string {\n if (enumValue === enumValue.toUpperCase()) {\n return enumValue.charAt(0).toUpperCase() + enumValue.slice(1).toLowerCase();\n }\n\n return enumValue;\n}\n\n/**\n * Interface for the MongoDB utility object to enable explicit type annotation.\n * Required to avoid TS7056 (inferred type exceeds maximum serialization length).\n */\ninterface I_MongoUtils {\n createGenericFields: () => I_GenericDocument;\n applyPlugins: <T>(schema: T_MongooseShema<T>, plugins: Array<T_MongoosePlugin | false>) => void;\n applyMiddlewares: <T extends Partial<C_Document>>(schema: T_MongooseShema<T>, middlewares: I_MongooseModelMiddleware<T>[]) => void;\n createGenericSchema: (mongoose: typeof mongooseRaw) => T_MongooseShema<I_GenericDocument>;\n createSchema: <T, R extends string = string>(options: I_CreateSchemaOptions<T, R>) => T_MongooseShema<T>;\n createModel: <T extends Partial<C_Document>, R extends string = string>(options: I_CreateModelOptions<T, R>) => I_ExtendedModel<T>;\n validator: {\n isRequired: <T>() => (this: T, value: unknown) => Promise<boolean>;\n isUnique: <T extends { constructor: { exists: (query: { [key: string]: unknown }) => Promise<unknown> } }>(fields: string[]) => (this: T, value: unknown) => Promise<boolean>;\n matchesRegex: (regexArray: RegExp[]) => (value: string) => Promise<boolean>;\n };\n migrate: {\n getModule: () => Promise<typeof migrate>;\n setConfig: (options: Partial<migrate.config.Config> & { moduleSystem?: 'commonjs' | 'esm' }) => void;\n };\n regexify: <T>(filter?: T_QueryFilter<T>, fields?: (keyof T | string)[]) => T_QueryFilter<T>;\n isDynamicVirtual: <T, R extends string>(options?: T_VirtualOptions<T, R>) => options is I_DynamicVirtualOptions<T, R>;\n getNewRecords: <T extends I_GenericDocument>(controller: MongoController<T>, recordsToCheck: T[], filterFn: (existingRecord: T_WithId<T>, newRecord: T) => boolean) => Promise<T[]>;\n getExistingRecords: <T extends I_GenericDocument>(controller: MongoController<T>, recordsToCheck: T[], filterFn: (existingRecord: T_WithId<T>, newRecord: T) => boolean) => Promise<T_WithId<T>[]>;\n}\n\n/**\n * MongoDB utility object providing comprehensive database operations and utilities.\n * This object contains methods for creating generic fields, applying plugins and middlewares,\n * creating schemas and models, validation functions, migration utilities, and regex filtering.\n */\nexport const mongo: I_MongoUtils = {\n /**\n * Creates generic fields that are commonly used across MongoDB documents.\n * This function generates standard fields including a UUID, deletion flag, and timestamps\n * that can be applied to any document schema.\n *\n * @returns An object containing generic document fields (id, isDel, createdAt, updatedAt).\n */\n createGenericFields(): I_GenericDocument {\n return {\n id: randomUUID(),\n isDel: false,\n createdAt: new Date(),\n updatedAt: new Date(),\n };\n },\n /**\n * Applies plugins to a Mongoose schema.\n * This function filters out falsy plugins and applies the remaining valid plugins\n * to the provided schema.\n *\n * @param schema - The Mongoose schema to apply plugins to.\n * @param plugins - An array of plugin functions or false values to filter and apply.\n */\n applyPlugins<T>(schema: T_MongooseShema<T>, plugins: Array<T_MongoosePlugin | false>) {\n plugins\n .filter((plugin): plugin is T_MongoosePlugin => typeof plugin === 'function')\n .forEach(plugin => schema.plugin(plugin));\n },\n /**\n * Applies middleware functions to a Mongoose schema.\n * This function configures pre and post middleware for specified methods on the schema.\n *\n * @param schema - The Mongoose schema to apply middleware to.\n * @param middlewares - An array of middleware configurations with method, pre, and post functions.\n */\n applyMiddlewares<T extends Partial<C_Document>>(\n schema: T_MongooseShema<T>,\n middlewares: I_MongooseModelMiddleware<T>[],\n ) {\n middlewares.forEach(({ method, pre, post }) => {\n if (method && pre) {\n schema.pre(method as RegExp, pre);\n }\n\n if (method && post) {\n schema.post(method as RegExp, post);\n }\n });\n },\n /**\n * Creates a generic Mongoose schema with common fields.\n * This function creates a base schema with UUID field and deletion flag,\n * configured with automatic timestamps.\n *\n * @param mongoose - The Mongoose instance to create the schema with.\n * @returns A Mongoose schema with generic document fields.\n */\n createGenericSchema(mongoose: typeof mongooseRaw) {\n return new mongoose.Schema<I_GenericDocument>(\n {\n id: { type: String, default: () => randomUUID(), unique: true },\n isDel: { type: Boolean, default: false },\n },\n { timestamps: true },\n );\n },\n /**\n * Creates a Mongoose schema with optional virtual fields and generic fields.\n * This function creates a new Mongoose schema from the provided schema definition,\n * optionally adds virtual fields, and includes generic fields (unless standalone is true).\n *\n * @param options - Configuration options including mongoose instance, schema definition, virtuals, and standalone flag.\n * @param options.mongoose - The Mongoose instance to use for schema creation.\n * @param options.schema - The schema definition object.\n * @param options.virtuals - Optional array of virtual field configurations.\n * @param options.standalone - Whether to exclude generic fields (default: false).\n * @returns A configured Mongoose schema.\n */\n createSchema<T, R extends string = string>({\n mongoose,\n schema,\n virtuals = [],\n standalone = false,\n }: I_CreateSchemaOptions<T, R>): T_MongooseShema<T> {\n const createdSchema = new mongoose.Schema<T>(schema, {\n toJSON: { virtuals: true }, // So `res.json()` and other `JSON.stringify()` functions include virtuals\n toObject: { virtuals: true }, // So `console.log()` and other functions that use `toObject()` include virtuals\n });\n\n virtuals.forEach(({ name, options, get }) => {\n if (mongo.isDynamicVirtual<T, R>(options)) {\n const schemaStatics = createdSchema.statics as Record<string, unknown>;\n\n if (!schemaStatics['_dynamicVirtuals']) {\n schemaStatics['_dynamicVirtuals'] = [];\n }\n\n (schemaStatics['_dynamicVirtuals'] as I_DynamicVirtualConfig<T>[]).push({\n name: name as string,\n options,\n });\n\n const virtualInstance = createdSchema.virtual(name as string);\n\n if (get) {\n virtualInstance.get(get);\n }\n else {\n virtualInstance.get(function (this: T & { _populated?: { [key: string]: unknown } }) {\n return this._populated?.[name as string] || (options?.count ? 0 : (options?.justOne ? null : []));\n });\n }\n }\n else {\n const virtualInstance = createdSchema.virtual(name as string, options);\n\n if (get) {\n virtualInstance.get(get);\n }\n }\n });\n\n if (!standalone) {\n createdSchema.add(mongo.createGenericSchema(mongoose));\n }\n\n return createdSchema;\n },\n /**\n * Creates a Mongoose model with plugins, middleware, and pagination support.\n * This function creates a model from a schema with optional pagination and aggregation plugins,\n * and applies any specified middleware. If a model with the same name already exists, it returns the existing model.\n *\n * @param options - Configuration options including mongoose instance, model name, schema, and feature flags.\n * @param options.mongoose - The Mongoose instance to use for model creation.\n * @param options.name - The name of the model to create.\n * @param options.schema - The schema definition for the model.\n * @param options.pagination - Whether to enable pagination plugin (default: false).\n * @param options.aggregate - Whether to enable aggregation pagination plugin (default: false).\n * @param options.virtuals - Optional array of virtual field configurations.\n * @param options.middlewares - Optional array of middleware configurations.\n * @returns A configured Mongoose model with extended functionality.\n * @throws {Error} When the model name is not provided.\n */\n createModel<T extends Partial<C_Document>, R extends string = string>({\n mongoose: currentMongooseInstance,\n name,\n schema,\n virtuals = [],\n pagination = true,\n aggregate = true,\n middlewares = [],\n }: I_CreateModelOptions<T, R>): I_ExtendedModel<T> {\n if (!name) {\n throw new Error('Model name is required.');\n }\n\n if (currentMongooseInstance.models[name]) {\n return currentMongooseInstance.models[name] as I_ExtendedModel<T>;\n }\n\n const createdSchema = mongo.createSchema({ mongoose: currentMongooseInstance, schema, virtuals });\n\n if (pagination || aggregate) {\n mongo.applyPlugins<T>(createdSchema, [\n pagination && mongoosePaginate,\n aggregate && aggregatePaginate,\n ]);\n }\n\n mongo.applyMiddlewares<T>(createdSchema, middlewares);\n\n const model = currentMongooseInstance.model<T>(name, createdSchema) as I_ExtendedModel<T>;\n\n if (virtuals.length > 0) {\n (model as any)._virtualConfigs = virtuals;\n }\n\n return model;\n },\n /**\n * Validation utilities for Mongoose schemas.\n * This object provides common validation functions that can be used in Mongoose schema definitions.\n */\n validator: {\n /**\n * Creates a required field validator.\n * This function returns a validator that checks if a field value is not empty\n * using the validate.isEmpty utility.\n *\n * @returns A validation function that returns true if the field is not empty.\n */\n isRequired<T>(): (this: T, value: unknown) => Promise<boolean> {\n return async function (this: T, value: unknown): Promise<boolean> {\n return !validate.isEmpty(value);\n };\n },\n /**\n * Creates a unique field validator.\n * This function returns a validator that checks if a field value is unique\n * across the specified fields in the collection.\n *\n * @param fields - An array of field names to check for uniqueness.\n * @returns A validation function that returns true if the value is unique across the specified fields.\n * @throws {Error} When fields is not a non-empty array of strings.\n */\n isUnique<T extends { constructor: { exists: (query: { [key: string]: unknown }) => Promise<unknown> } }>(fields: string[]) {\n return async function (this: T, value: unknown): Promise<boolean> {\n if (!Array.isArray(fields) || fields.length === 0) {\n throw new Error('Fields must be a non-empty array of strings.');\n }\n\n const query = { $or: fields.map(field => ({ [field]: value })) };\n const existingDocument = await this.constructor.exists(query);\n\n return !existingDocument;\n };\n },\n /**\n * Creates a regex pattern validator.\n * This function returns a validator that checks if a string value matches\n * all provided regular expressions.\n *\n * @param regexArray - An array of regular expressions to test against the value.\n * @returns A validation function that returns true if the value matches all regex patterns.\n * @throws {Error} When regexArray is not an array of valid RegExp objects.\n */\n matchesRegex(regexArray: RegExp[]): (value: string) => Promise<boolean> {\n return async (value: string): Promise<boolean> => {\n if (!Array.isArray(regexArray) || regexArray.some(r => !(r instanceof RegExp))) {\n throw new Error('regexArray must be an array of valid RegExp objects.');\n }\n\n return regexArray.every(regex => regex.test(value));\n };\n },\n },\n /**\n * Migration utilities for MongoDB.\n * This object extends the migrate-mongo library with additional configuration utilities.\n */\n migrate: {\n /**\n * Lazily loads the migrate-mongo module to avoid eager import overhead.\n * Use this to access migrate-mongo methods (up, down, status, create) programmatically.\n *\n * @returns A promise resolving to the migrate-mongo module.\n */\n async getModule(): Promise<typeof migrate> {\n return (await import('migrate-mongo')).default;\n },\n /**\n * Sets the migration configuration and updates .gitignore.\n * This function creates a migration configuration file and ensures it's properly\n * excluded from version control.\n *\n * @param options - Migration configuration options to write to the config file.\n */\n setConfig: (options: Partial<migrate.config.Config> & { moduleSystem?: 'commonjs' | 'esm' }) => {\n const optionsJS = `// This file is automatically generated by the Cyberskill CLI.\\nmodule.exports = ${JSON.stringify(options, null, 4)}`;\n\n writeFileSync(PATH.MIGRATE_MONGO_CONFIG, optionsJS);\n\n addGitIgnoreEntry(PATH.GIT_IGNORE, MIGRATE_MONGO_CONFIG);\n },\n },\n /**\n * Converts string values in a filter to regex patterns for case-insensitive search.\n * This function recursively processes a filter object and converts string values in specified fields\n * to MongoDB regex patterns that support accented character matching.\n *\n * @param filter - The filter object to process.\n * @param fields - An array of field names to convert to regex patterns.\n * @returns A new filter object with string values converted to regex patterns.\n */\n regexify<T>(filter?: T_QueryFilter<T>, fields?: (keyof T | string)[]): T_QueryFilter<T> {\n if (!filter) {\n return {} as T_QueryFilter<T>;\n }\n\n let newFilter = deepClone(filter);\n\n if (!fields || fields.length === 0) {\n return newFilter;\n }\n\n for (const field of fields) {\n const path = field.toString().split('.');\n const value = getNestedValue(newFilter, path);\n\n if (typeof value === 'string' && value.length > 0) {\n const regexValue = {\n $regex: `.*${regexSearchMapper(value)}.*`,\n $options: 'i',\n };\n\n newFilter = setNestedValue(newFilter, path, regexValue);\n }\n }\n\n return newFilter;\n },\n /**\n * Checks if a virtual options object has a dynamic ref function.\n *\n * @param options - The virtual options to check.\n * @returns True if the options contain a dynamic ref function.\n */\n isDynamicVirtual<T, R extends string = string>(options?: T_VirtualOptions<T, R>): options is I_DynamicVirtualOptions<T, R> {\n return Boolean(options && typeof options.ref === 'function');\n },\n\n /**\n * Generic utility function to get new records from the database\n * @param controller - MongoController instance\n * @param recordsToCheck - Array of records to check\n * @param filterFn - Function to determine if a record already exists\n * @returns Array of records that don't exist in the database\n */\n async getNewRecords<T extends I_GenericDocument>(\n controller: MongoController<T>,\n recordsToCheck: T[],\n filterFn: (existingRecord: T_WithId<T>, newRecord: T) => boolean,\n filter: Record<string, unknown> = {},\n ): Promise<T[]> {\n const existingRecords = await controller.findAll(filter as any);\n\n if (!existingRecords.success) {\n return recordsToCheck;\n }\n\n const filteredRecords = recordsToCheck.filter(newRecord =>\n !existingRecords.result.some((existingRecord: T_WithId<T>) =>\n filterFn(existingRecord, newRecord),\n ),\n );\n\n return filteredRecords;\n },\n\n /**\n * Generic utility function to get existing records that match the filter criteria\n * @param controller - MongoController instance\n * @param recordsToCheck - Array of records to check\n * @param filterFn - Function to determine if a record exists\n * @returns Array of existing records that match the filter criteria\n */\n async getExistingRecords<T extends I_GenericDocument>(\n controller: MongoController<T>,\n recordsToCheck: T[],\n filterFn: (existingRecord: T_WithId<T>, newRecord: T) => boolean,\n filter: Record<string, unknown> = {},\n ): Promise<T_WithId<T>[]> {\n const existingRecords = await controller.findAll(filter as any);\n\n if (!existingRecords.success) {\n return [];\n }\n\n const foundRecords = existingRecords.result.filter((existingRecord: T_WithId<T>) =>\n recordsToCheck.some((newRecord: T) =>\n filterFn(existingRecord, newRecord),\n ),\n );\n\n return foundRecords;\n },\n};\n\nexport { applyNestedPopulate } from './mongo.populate.js';\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"mongo.util.js","names":[],"sources":["../../../src/node/mongo/mongo.util.ts"],"sourcesContent":["import type migrate from 'migrate-mongo';\nimport type mongooseRaw from 'mongoose';\n\nimport aggregatePaginate from 'mongoose-aggregate-paginate-v2';\nimport mongoosePaginate from 'mongoose-paginate-v2';\nimport { randomUUID } from 'node:crypto';\n\nimport { getNestedValue, regexSearchMapper, setNestedValue } from '#util/index.js';\nimport { validate } from '#util/validate/index.js';\n\nimport type { MongoController } from './mongo.controller.js';\nimport type { C_Document, I_CreateModelOptions, I_CreateSchemaOptions, I_DynamicVirtualConfig, I_DynamicVirtualOptions, I_ExtendedModel, I_GenericDocument, I_MongooseModelMiddleware, T_MongoosePlugin, T_MongooseSchema, T_QueryFilter, T_VirtualOptions, T_WithId } from './mongo.type.js';\n\nimport { addGitIgnoreEntry, writeFileSync } from '../fs/index.js';\nimport { MIGRATE_MONGO_CONFIG, PATH } from '../path/index.js';\n\n/**\n * Converts enum values to proper model names.\n * Handles common naming conventions like converting 'USER' to 'User'.\n *\n * @param enumValue - The enum value to convert\n * @returns The converted model name\n */\nexport function convertEnumToModelName(enumValue: string): string {\n if (enumValue === enumValue.toUpperCase()) {\n return enumValue.charAt(0).toUpperCase() + enumValue.slice(1).toLowerCase();\n }\n\n return enumValue;\n}\n\n/**\n * Interface for the MongoDB utility object to enable explicit type annotation.\n * Required to avoid TS7056 (inferred type exceeds maximum serialization length).\n */\ninterface I_MongoUtils {\n createGenericFields: () => I_GenericDocument;\n applyPlugins: <T>(schema: T_MongooseSchema<T>, plugins: Array<T_MongoosePlugin | false>) => void;\n applyMiddlewares: <T extends Partial<C_Document>>(schema: T_MongooseSchema<T>, middlewares: I_MongooseModelMiddleware<T>[]) => void;\n createGenericSchema: (mongoose: typeof mongooseRaw) => T_MongooseSchema<I_GenericDocument>;\n createSchema: <T, R extends string = string>(options: I_CreateSchemaOptions<T, R>) => T_MongooseSchema<T>;\n createModel: <T extends Partial<C_Document>, R extends string = string>(options: I_CreateModelOptions<T, R>) => I_ExtendedModel<T>;\n validator: {\n isRequired: <T>() => (this: T, value: unknown) => Promise<boolean>;\n isUnique: <T extends { constructor: { exists: (query: { [key: string]: unknown }) => Promise<unknown> } }>(fields: string[]) => (this: T, value: unknown) => Promise<boolean>;\n matchesRegex: (regexArray: RegExp[]) => (value: string) => Promise<boolean>;\n };\n migrate: {\n getModule: () => Promise<typeof migrate>;\n setConfig: (options: Partial<migrate.config.Config> & { moduleSystem?: 'commonjs' | 'esm' }) => void;\n };\n regexify: <T>(filter?: T_QueryFilter<T>, fields?: (keyof T | string)[]) => T_QueryFilter<T>;\n isDynamicVirtual: <T, R extends string>(options?: T_VirtualOptions<T, R>) => options is I_DynamicVirtualOptions<T, R>;\n getNewRecords: <T extends I_GenericDocument>(controller: MongoController<T>, recordsToCheck: T[], filterFn: (existingRecord: T_WithId<T>, newRecord: T) => boolean, filter?: Record<string, unknown>) => Promise<T[]>;\n getExistingRecords: <T extends I_GenericDocument>(controller: MongoController<T>, recordsToCheck: T[], filterFn: (existingRecord: T_WithId<T>, newRecord: T) => boolean, filter?: Record<string, unknown>) => Promise<T_WithId<T>[]>;\n}\n\n/**\n * MongoDB utility object providing comprehensive database operations and utilities.\n * This object contains methods for creating generic fields, applying plugins and middlewares,\n * creating schemas and models, validation functions, migration utilities, and regex filtering.\n */\nexport const mongo: I_MongoUtils = {\n /**\n * Creates generic fields that are commonly used across MongoDB documents.\n * This function generates standard fields including a UUID, deletion flag, and timestamps\n * that can be applied to any document schema.\n *\n * @returns An object containing generic document fields (id, isDel, createdAt, updatedAt).\n */\n createGenericFields(): I_GenericDocument {\n return {\n id: randomUUID(),\n isDel: false,\n createdAt: new Date(),\n updatedAt: new Date(),\n };\n },\n /**\n * Applies plugins to a Mongoose schema.\n * This function filters out falsy plugins and applies the remaining valid plugins\n * to the provided schema.\n *\n * @param schema - The Mongoose schema to apply plugins to.\n * @param plugins - An array of plugin functions or false values to filter and apply.\n */\n applyPlugins<T>(schema: T_MongooseSchema<T>, plugins: Array<T_MongoosePlugin | false>) {\n plugins\n .filter((plugin): plugin is T_MongoosePlugin => typeof plugin === 'function')\n .forEach(plugin => schema.plugin(plugin));\n },\n /**\n * Applies middleware functions to a Mongoose schema.\n * This function configures pre and post middleware for specified methods on the schema.\n *\n * @param schema - The Mongoose schema to apply middleware to.\n * @param middlewares - An array of middleware configurations with method, pre, and post functions.\n */\n applyMiddlewares<T extends Partial<C_Document>>(\n schema: T_MongooseSchema<T>,\n middlewares: I_MongooseModelMiddleware<T>[],\n ) {\n middlewares.forEach(({ method, pre, post }) => {\n if (method && pre) {\n schema.pre(method as RegExp, pre);\n }\n\n if (method && post) {\n schema.post(method as RegExp, post);\n }\n });\n },\n /**\n * Creates a generic Mongoose schema with common fields.\n * This function creates a base schema with UUID field and deletion flag,\n * configured with automatic timestamps.\n *\n * @param mongoose - The Mongoose instance to create the schema with.\n * @returns A Mongoose schema with generic document fields.\n */\n createGenericSchema(mongoose: typeof mongooseRaw) {\n return new mongoose.Schema<I_GenericDocument>(\n {\n id: { type: String, default: () => randomUUID(), unique: true },\n isDel: { type: Boolean, default: false },\n },\n { timestamps: true },\n );\n },\n /**\n * Creates a Mongoose schema with optional virtual fields and generic fields.\n * This function creates a new Mongoose schema from the provided schema definition,\n * optionally adds virtual fields, and includes generic fields (unless standalone is true).\n *\n * @param options - Configuration options including mongoose instance, schema definition, virtuals, and standalone flag.\n * @param options.mongoose - The Mongoose instance to use for schema creation.\n * @param options.schema - The schema definition object.\n * @param options.virtuals - Optional array of virtual field configurations.\n * @param options.standalone - Whether to exclude generic fields (default: false).\n * @returns A configured Mongoose schema.\n */\n createSchema<T, R extends string = string>({\n mongoose,\n schema,\n virtuals = [],\n standalone = false,\n }: I_CreateSchemaOptions<T, R>): T_MongooseSchema<T> {\n const createdSchema = new mongoose.Schema<T>(schema, {\n toJSON: { virtuals: true }, // So `res.json()` and other `JSON.stringify()` functions include virtuals\n toObject: { virtuals: true }, // So `console.log()` and other functions that use `toObject()` include virtuals\n });\n\n virtuals.forEach(({ name, options, get }) => {\n if (mongo.isDynamicVirtual<T, R>(options)) {\n const schemaStatics = createdSchema.statics as Record<string, unknown>;\n\n if (!schemaStatics['_dynamicVirtuals']) {\n schemaStatics['_dynamicVirtuals'] = [];\n }\n\n (schemaStatics['_dynamicVirtuals'] as I_DynamicVirtualConfig<T>[]).push({\n name: name as string,\n options,\n });\n\n const virtualInstance = createdSchema.virtual(name as string);\n\n if (get) {\n virtualInstance.get(get);\n }\n else {\n virtualInstance.get(function (this: T & { _populated?: { [key: string]: unknown } }) {\n return this._populated?.[name as string] || (options?.count ? 0 : (options?.justOne ? null : []));\n });\n }\n }\n else {\n const virtualInstance = createdSchema.virtual(name as string, options);\n\n if (get) {\n virtualInstance.get(get);\n }\n }\n });\n\n if (!standalone) {\n createdSchema.add(mongo.createGenericSchema(mongoose));\n }\n\n return createdSchema;\n },\n /**\n * Creates a Mongoose model with plugins, middleware, and pagination support.\n * This function creates a model from a schema with optional pagination and aggregation plugins,\n * and applies any specified middleware. If a model with the same name already exists, it returns the existing model.\n *\n * @param options - Configuration options including mongoose instance, model name, schema, and feature flags.\n * @param options.mongoose - The Mongoose instance to use for model creation.\n * @param options.name - The name of the model to create.\n * @param options.schema - The schema definition for the model.\n * @param options.pagination - Whether to enable pagination plugin (default: false).\n * @param options.aggregate - Whether to enable aggregation pagination plugin (default: false).\n * @param options.virtuals - Optional array of virtual field configurations.\n * @param options.middlewares - Optional array of middleware configurations.\n * @returns A configured Mongoose model with extended functionality.\n * @throws {Error} When the model name is not provided.\n */\n createModel<T extends Partial<C_Document>, R extends string = string>({\n mongoose: currentMongooseInstance,\n name,\n schema,\n virtuals = [],\n pagination = true,\n aggregate = true,\n middlewares = [],\n }: I_CreateModelOptions<T, R>): I_ExtendedModel<T> {\n if (!name) {\n throw new Error('Model name is required.');\n }\n\n if (currentMongooseInstance.models[name]) {\n return currentMongooseInstance.models[name] as I_ExtendedModel<T>;\n }\n\n const createdSchema = mongo.createSchema({ mongoose: currentMongooseInstance, schema, virtuals });\n\n if (pagination || aggregate) {\n mongo.applyPlugins<T>(createdSchema, [\n pagination && mongoosePaginate,\n aggregate && aggregatePaginate,\n ]);\n }\n\n mongo.applyMiddlewares<T>(createdSchema, middlewares);\n\n const model = currentMongooseInstance.model<T>(name, createdSchema) as I_ExtendedModel<T>;\n\n if (virtuals.length > 0) {\n (model as any)._virtualConfigs = virtuals;\n }\n\n return model;\n },\n /**\n * Validation utilities for Mongoose schemas.\n * This object provides common validation functions that can be used in Mongoose schema definitions.\n */\n validator: {\n /**\n * Creates a required field validator.\n * This function returns a validator that checks if a field value is not empty\n * using the validate.isEmpty utility.\n *\n * @returns A validation function that returns true if the field is not empty.\n */\n isRequired<T>(): (this: T, value: unknown) => Promise<boolean> {\n return async function (this: T, value: unknown): Promise<boolean> {\n return !validate.isEmpty(value);\n };\n },\n /**\n * Creates a unique field validator.\n * This function returns a validator that checks if a field value is unique\n * across the specified fields in the collection.\n *\n * @param fields - An array of field names to check for uniqueness.\n * @returns A validation function that returns true if the value is unique across the specified fields.\n * @throws {Error} When fields is not a non-empty array of strings.\n */\n isUnique<T extends { constructor: { exists: (query: { [key: string]: unknown }) => Promise<unknown> } }>(fields: string[]) {\n return async function (this: T, value: unknown): Promise<boolean> {\n if (!Array.isArray(fields) || fields.length === 0) {\n throw new Error('Fields must be a non-empty array of strings.');\n }\n\n const query = { $or: fields.map(field => ({ [field]: value })) };\n const existingDocument = await this.constructor.exists(query);\n\n return !existingDocument;\n };\n },\n /**\n * Creates a regex pattern validator.\n * This function returns a validator that checks if a string value matches\n * all provided regular expressions.\n *\n * @param regexArray - An array of regular expressions to test against the value.\n * @returns A validation function that returns true if the value matches all regex patterns.\n * @throws {Error} When regexArray is not an array of valid RegExp objects.\n */\n matchesRegex(regexArray: RegExp[]): (value: string) => Promise<boolean> {\n return async (value: string): Promise<boolean> => {\n if (!Array.isArray(regexArray) || regexArray.some(r => !(r instanceof RegExp))) {\n throw new Error('regexArray must be an array of valid RegExp objects.');\n }\n\n return regexArray.every(regex => regex.test(value));\n };\n },\n },\n /**\n * Migration utilities for MongoDB.\n * This object extends the migrate-mongo library with additional configuration utilities.\n */\n migrate: {\n /**\n * Lazily loads the migrate-mongo module to avoid eager import overhead.\n * Use this to access migrate-mongo methods (up, down, status, create) programmatically.\n *\n * @returns A promise resolving to the migrate-mongo module.\n */\n async getModule(): Promise<typeof migrate> {\n return (await import('migrate-mongo')).default;\n },\n /**\n * Sets the migration configuration and updates .gitignore.\n * This function creates a migration configuration file and ensures it's properly\n * excluded from version control.\n *\n * @param options - Migration configuration options to write to the config file.\n */\n setConfig: (options: Partial<migrate.config.Config> & { moduleSystem?: 'commonjs' | 'esm' }) => {\n const optionsJS = `// This file is automatically generated by the Cyberskill CLI.\\nmodule.exports = ${JSON.stringify(options, null, 4)}`;\n\n writeFileSync(PATH.MIGRATE_MONGO_CONFIG, optionsJS);\n\n addGitIgnoreEntry(PATH.GIT_IGNORE, MIGRATE_MONGO_CONFIG);\n },\n },\n /**\n * Converts string values in a filter to regex patterns for case-insensitive search.\n * This function recursively processes a filter object and converts string values in specified fields\n * to MongoDB regex patterns that support accented character matching.\n *\n * @param filter - The filter object to process.\n * @param fields - An array of field names to convert to regex patterns.\n * @returns A new filter object with string values converted to regex patterns.\n */\n regexify<T>(filter?: T_QueryFilter<T>, fields?: (keyof T | string)[]): T_QueryFilter<T> {\n if (!filter) {\n return {} as T_QueryFilter<T>;\n }\n\n let newFilter = { ...filter };\n\n if (!fields || fields.length === 0) {\n return newFilter;\n }\n\n const MAX_REGEX_INPUT_LENGTH = 200;\n\n for (const field of fields) {\n const path = field.toString().split('.');\n const value = getNestedValue(newFilter, path);\n\n if (typeof value === 'string' && value.length > 0 && value.length <= MAX_REGEX_INPUT_LENGTH) {\n const regexValue = {\n $regex: `.*${regexSearchMapper(value)}.*`,\n $options: 'i',\n };\n\n newFilter = setNestedValue(newFilter, path, regexValue);\n }\n }\n\n return newFilter;\n },\n /**\n * Checks if a virtual options object has a dynamic ref function.\n *\n * @param options - The virtual options to check.\n * @returns True if the options contain a dynamic ref function.\n */\n isDynamicVirtual<T, R extends string = string>(options?: T_VirtualOptions<T, R>): options is I_DynamicVirtualOptions<T, R> {\n return Boolean(options && typeof options.ref === 'function');\n },\n\n /**\n * Generic utility function to get new records from the database\n * @param controller - MongoController instance\n * @param recordsToCheck - Array of records to check\n * @param filterFn - Function to determine if a record already exists\n * @returns Array of records that don't exist in the database\n */\n async getNewRecords<T extends I_GenericDocument>(\n controller: MongoController<T>,\n recordsToCheck: T[],\n filterFn: (existingRecord: T_WithId<T>, newRecord: T) => boolean,\n filter: Record<string, unknown> = {},\n ): Promise<T[]> {\n const existingRecords = await controller.findAll(filter as any);\n\n if (!existingRecords.success) {\n throw new Error(`Failed to query existing records: ${existingRecords.message}`);\n }\n\n const filteredRecords = recordsToCheck.filter(newRecord =>\n !existingRecords.result.some((existingRecord: T_WithId<T>) =>\n filterFn(existingRecord, newRecord),\n ),\n );\n\n return filteredRecords;\n },\n\n /**\n * Generic utility function to get existing records that match the filter criteria\n * @param controller - MongoController instance\n * @param recordsToCheck - Array of records to check\n * @param filterFn - Function to determine if a record exists\n * @returns Array of existing records that match the filter criteria\n * @throws {Error} When the database query fails — prevents silent data inconsistency.\n */\n async getExistingRecords<T extends I_GenericDocument>(\n controller: MongoController<T>,\n recordsToCheck: T[],\n filterFn: (existingRecord: T_WithId<T>, newRecord: T) => boolean,\n filter: Record<string, unknown> = {},\n ): Promise<T_WithId<T>[]> {\n const existingRecords = await controller.findAll(filter as any);\n\n if (!existingRecords.success) {\n throw new Error(`Failed to query existing records: ${existingRecords.message}`);\n }\n\n const foundRecords = existingRecords.result.filter((existingRecord: T_WithId<T>) =>\n recordsToCheck.some((newRecord: T) =>\n filterFn(existingRecord, newRecord),\n ),\n );\n\n return foundRecords;\n },\n};\n\nexport { applyNestedPopulate } from './mongo.populate.js';\n"],"mappings":"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"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { I_CommandContext } from '../command/index.js';
|
|
2
1
|
export declare const WORKING_DIRECTORY: string;
|
|
3
2
|
export declare const CYBERSKILL_PACKAGE_NAME = "@cyberskill/shared";
|
|
4
3
|
export declare const NODE_MODULES = "node_modules";
|
|
@@ -72,17 +71,15 @@ export declare const PATH: {
|
|
|
72
71
|
* This function generates a configuration object for Git hooks that includes
|
|
73
72
|
* pre-commit and commit-msg hooks, with an optional pre-push hook for the current project.
|
|
74
73
|
*
|
|
75
|
-
* @param context - Context object containing project information.
|
|
76
|
-
* @param context.isCurrentProject - Whether this is the current project being worked on.
|
|
77
74
|
* @returns A Git hooks configuration object with appropriate commands for each hook.
|
|
78
75
|
*/
|
|
79
|
-
export declare function createGitHooksConfig(
|
|
76
|
+
export declare function createGitHooksConfig(): {
|
|
77
|
+
'pre-commit': string;
|
|
78
|
+
'commit-msg': string;
|
|
80
79
|
'pre-push': {
|
|
81
80
|
raw: boolean;
|
|
82
81
|
cmd: string;
|
|
83
82
|
};
|
|
84
|
-
'pre-commit': string;
|
|
85
|
-
'commit-msg': string;
|
|
86
83
|
};
|
|
87
84
|
export declare const command: {
|
|
88
85
|
simpleGitHooks: () => Promise<string>;
|
|
@@ -4,35 +4,41 @@ import { E_PackageType as n } from "../package/package.type.js";
|
|
|
4
4
|
import { setupPackages as ee } from "../package/package.util.js";
|
|
5
5
|
import { formatCommand as r, rawCommand as i } from "../command/command.util.js";
|
|
6
6
|
import { join as a, resolveWorkingPath as o } from "./path.util.js";
|
|
7
|
-
import
|
|
8
|
-
var
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
7
|
+
import s from "fs-extra";
|
|
8
|
+
var c = e().CWD, l = "@cyberskill/shared", u = "node_modules", d = "dist", f = "public", p = "package.json", m = "package-lock.json", h = "tsconfig.json", g = ".gitignore", _ = ".simple-git-hooks.json", v = "pnpm-lock.yaml", y = ".git/hooks/", b = ".git/COMMIT_EDITMSG", x = ".git/info/exclude", S = ".migrate-mongo.config.js", C = (() => {
|
|
9
|
+
try {
|
|
10
|
+
return s.readJsonSync(o("package.json")).name === "@cyberskill/shared" ? a(c, d) : a(c, u, l, d);
|
|
11
|
+
} catch {
|
|
12
|
+
return a(c, u, l, d);
|
|
13
|
+
}
|
|
14
|
+
})(), te = "cyberskill", w = "src/node/cli/index.ts", T = "eslint", E = "eslint", D = "vitest", O = "vitest", k = "@commitlint/cli", A = "@commitlint/config-conventional", j = "commitlint", M = "lint-staged", N = "lint-staged", P = "typescript", F = "tsc", I = "tsx", L = "git", R = "pnpm", z = "pnpm exec", B = "simple-git-hooks", V = "simple-git-hooks", H = "@eslint/config-inspector", U = "eslint-config-inspector", W = "node-modules-inspector", G = "node-modules-inspector", K = "migrate-mongo", q = "./node_modules/migrate-mongo/bin/migrate-mongo", J = "storybook", Y = "storybook", X = "@vudovn/ag-kit", Z = ".agent", Q = {
|
|
15
|
+
CYBERSKILL_DIRECTORY: C,
|
|
16
|
+
WORKING_DIRECTORY: c,
|
|
17
|
+
PUBLIC_DIRECTORY: o(f),
|
|
18
|
+
TS_CONFIG: o(h),
|
|
19
|
+
GIT_IGNORE: o(g),
|
|
20
|
+
GIT_HOOK: o(y),
|
|
21
|
+
GIT_COMMIT_MSG: o(b),
|
|
22
|
+
GIT_EXCLUDE: o(x),
|
|
23
|
+
SIMPLE_GIT_HOOKS_JSON: o(_),
|
|
24
|
+
PACKAGE_JSON: o(p),
|
|
25
|
+
PACKAGE_LOCK_JSON: o(m),
|
|
26
|
+
PNPM_LOCK_YAML: o(v),
|
|
27
|
+
NODE_MODULES: o(u),
|
|
28
|
+
MIGRATE_MONGO_CONFIG: o(S),
|
|
29
|
+
LINT_STAGED_CONFIG: o(`${C}/config/lint-staged/index.js`),
|
|
30
|
+
COMMITLINT_CONFIG: o(`${C}/config/commitlint/index.js`),
|
|
31
|
+
VITEST_UNIT_CONFIG: o(`${C}/config/vitest/vitest.unit.js`),
|
|
32
|
+
VITEST_E2E_CONFIG: o(`${C}/config/vitest/vitest.e2e.js`),
|
|
33
|
+
STORYBOOK_MAIN_CONFIG: o(`${C}/config/storybook/storybook.main.js`),
|
|
34
|
+
STORYBOOK_PREVIEW_CONFIG: o(`${C}/config/storybook/storybook.preview.js`),
|
|
29
35
|
DOT_AGENT: o(Z)
|
|
30
36
|
};
|
|
31
|
-
function ne(
|
|
37
|
+
function ne() {
|
|
32
38
|
return {
|
|
33
39
|
"pre-commit": N,
|
|
34
40
|
"commit-msg": j,
|
|
35
|
-
|
|
41
|
+
"pre-push": i(`git pull && ${R} test`)
|
|
36
42
|
};
|
|
37
43
|
}
|
|
38
44
|
function $({ type: e, packages: n, command: a }) {
|
|
@@ -211,6 +217,6 @@ var re = /^[\w-]+$/, ie = {
|
|
|
211
217
|
})
|
|
212
218
|
};
|
|
213
219
|
//#endregion
|
|
214
|
-
export { X as AG_KIT_PACKAGE_NAME,
|
|
220
|
+
export { X as AG_KIT_PACKAGE_NAME, d as BUILD_DIRECTORY, j as COMMIT_LINT_CLI, A as COMMIT_LINT_CONVENTIONAL_CONFIG_PACKAGE_NAME, k as COMMIT_LINT_PACKAGE_NAME, te as CYBERSKILL_CLI, w as CYBERSKILL_CLI_PATH, C as CYBERSKILL_DIRECTORY, l as CYBERSKILL_PACKAGE_NAME, Z as DOT_AGENT, E as ESLINT_CLI, U as ESLINT_INSPECT_CLI, H as ESLINT_INSPECT_PACKAGE_NAME, T as ESLINT_PACKAGE_NAME, L as GIT_CLI, b as GIT_COMMIT_EDITMSG, x as GIT_EXCLUDE, y as GIT_HOOK, g as GIT_IGNORE, N as LINT_STAGED_CLI, M as LINT_STAGED_PACKAGE_NAME, q as MIGRATE_MONGO_CLI, S as MIGRATE_MONGO_CONFIG, K as MIGRATE_MONGO_PACKAGE_NAME, u as NODE_MODULES, G as NODE_MODULES_INSPECT_CLI, W as NODE_MODULES_INSPECT_PACKAGE_NAME, p as PACKAGE_JSON, m as PACKAGE_LOCK_JSON, Q as PATH, R as PNPM_CLI, z as PNPM_EXEC_CLI, v as PNPM_LOCK_YAML, f as PUBLIC_DIRECTORY, B as SIMPLE_GIT_HOOKS_PACKAGE_NAME, V as SIMPLE_GIT_HOOK_CLI, _ as SIMPLE_GIT_HOOK_JSON, Y as STORYBOOK_CLI, J as STORYBOOK_PACKAGE_NAME, h as TSCONFIG_JSON, F as TSC_CLI, P as TSC_PACKAGE_NAME, I as TSX_CLI, O as VITEST_CLI, D as VITEST_PACKAGE_NAME, c as WORKING_DIRECTORY, ie as command, ne as createGitHooksConfig };
|
|
215
221
|
|
|
216
222
|
//# sourceMappingURL=path.constant.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"path.constant.js","names":[],"sources":["../../../src/node/path/path.constant.ts"],"sourcesContent":["import fsExtra from 'fs-extra';\n\nimport { getEnv } from '#config/env/index.js';\n\nimport type { I_CommandContext } from '../command/index.js';\nimport type { I_PackageInput, I_PackageJson } from '../package/index.js';\n\nimport { E_CommandType, formatCommand, rawCommand } from '../command/index.js';\nimport { E_PackageType, setupPackages } from '../package/index.js';\nimport { join, resolveWorkingPath } from './path.util.js';\n\nconst env = getEnv();\n\nexport const WORKING_DIRECTORY = env.CWD;\nexport const CYBERSKILL_PACKAGE_NAME = '@cyberskill/shared';\nexport const NODE_MODULES = 'node_modules';\nexport const BUILD_DIRECTORY = 'dist';\nexport const PUBLIC_DIRECTORY = 'public';\nexport const PACKAGE_JSON = 'package.json';\nexport const PACKAGE_LOCK_JSON = 'package-lock.json';\nexport const TSCONFIG_JSON = 'tsconfig.json';\nexport const GIT_IGNORE = '.gitignore';\nexport const SIMPLE_GIT_HOOK_JSON = '.simple-git-hooks.json';\nexport const PNPM_LOCK_YAML = 'pnpm-lock.yaml';\nexport const GIT_HOOK = '.git/hooks/';\nexport const GIT_COMMIT_EDITMSG = '.git/COMMIT_EDITMSG';\nexport const GIT_EXCLUDE = '.git/info/exclude';\nexport const MIGRATE_MONGO_CONFIG = '.migrate-mongo.config.js';\nexport const CYBERSKILL_DIRECTORY = (() => {\n const packageJson = fsExtra.readJsonSync(resolveWorkingPath(PACKAGE_JSON)) as I_PackageJson;\n\n const baseDirectory = packageJson.name === CYBERSKILL_PACKAGE_NAME\n ? join(WORKING_DIRECTORY, BUILD_DIRECTORY)\n : join(WORKING_DIRECTORY, NODE_MODULES, CYBERSKILL_PACKAGE_NAME, BUILD_DIRECTORY);\n\n return baseDirectory;\n})();\nexport const CYBERSKILL_CLI = 'cyberskill';\nexport const CYBERSKILL_CLI_PATH = 'src/node/cli/index.ts';\nexport const ESLINT_PACKAGE_NAME = 'eslint';\nexport const ESLINT_CLI = 'eslint';\nexport const VITEST_PACKAGE_NAME = 'vitest';\nexport const VITEST_CLI = 'vitest';\nexport const COMMIT_LINT_PACKAGE_NAME = '@commitlint/cli';\nexport const COMMIT_LINT_CONVENTIONAL_CONFIG_PACKAGE_NAME = '@commitlint/config-conventional';\nexport const COMMIT_LINT_CLI = 'commitlint';\nexport const LINT_STAGED_PACKAGE_NAME = 'lint-staged';\nexport const LINT_STAGED_CLI = 'lint-staged';\nexport const TSC_PACKAGE_NAME = 'typescript';\nexport const TSC_CLI = 'tsc';\nexport const TSX_CLI = 'tsx';\nexport const GIT_CLI = 'git';\nexport const PNPM_CLI = 'pnpm';\nexport const PNPM_EXEC_CLI = 'pnpm exec';\nexport const SIMPLE_GIT_HOOKS_PACKAGE_NAME = 'simple-git-hooks';\nexport const SIMPLE_GIT_HOOK_CLI = 'simple-git-hooks';\nexport const ESLINT_INSPECT_PACKAGE_NAME = '@eslint/config-inspector';\nexport const ESLINT_INSPECT_CLI = 'eslint-config-inspector';\nexport const NODE_MODULES_INSPECT_PACKAGE_NAME = 'node-modules-inspector';\nexport const NODE_MODULES_INSPECT_CLI = 'node-modules-inspector';\nexport const MIGRATE_MONGO_PACKAGE_NAME = 'migrate-mongo';\nexport const MIGRATE_MONGO_CLI = './node_modules/migrate-mongo/bin/migrate-mongo';\nexport const STORYBOOK_PACKAGE_NAME = 'storybook';\nexport const STORYBOOK_CLI = 'storybook';\nexport const AG_KIT_PACKAGE_NAME = '@vudovn/ag-kit';\nexport const DOT_AGENT = '.agent';\n\nexport const PATH = {\n CYBERSKILL_DIRECTORY,\n WORKING_DIRECTORY,\n PUBLIC_DIRECTORY: resolveWorkingPath(PUBLIC_DIRECTORY),\n TS_CONFIG: resolveWorkingPath(TSCONFIG_JSON),\n GIT_IGNORE: resolveWorkingPath(GIT_IGNORE),\n GIT_HOOK: resolveWorkingPath(GIT_HOOK),\n GIT_COMMIT_MSG: resolveWorkingPath(GIT_COMMIT_EDITMSG),\n GIT_EXCLUDE: resolveWorkingPath(GIT_EXCLUDE),\n SIMPLE_GIT_HOOKS_JSON: resolveWorkingPath(SIMPLE_GIT_HOOK_JSON),\n PACKAGE_JSON: resolveWorkingPath(PACKAGE_JSON),\n PACKAGE_LOCK_JSON: resolveWorkingPath(PACKAGE_LOCK_JSON),\n PNPM_LOCK_YAML: resolveWorkingPath(PNPM_LOCK_YAML),\n NODE_MODULES: resolveWorkingPath(NODE_MODULES),\n MIGRATE_MONGO_CONFIG: resolveWorkingPath(MIGRATE_MONGO_CONFIG),\n LINT_STAGED_CONFIG: resolveWorkingPath(`${CYBERSKILL_DIRECTORY}/config/lint-staged/index.js`),\n COMMITLINT_CONFIG: resolveWorkingPath(`${CYBERSKILL_DIRECTORY}/config/commitlint/index.js`),\n VITEST_UNIT_CONFIG: resolveWorkingPath(`${CYBERSKILL_DIRECTORY}/config/vitest/vitest.unit.js`),\n VITEST_E2E_CONFIG: resolveWorkingPath(`${CYBERSKILL_DIRECTORY}/config/vitest/vitest.e2e.js`),\n STORYBOOK_MAIN_CONFIG: resolveWorkingPath(`${CYBERSKILL_DIRECTORY}/config/storybook/storybook.main.js`),\n STORYBOOK_PREVIEW_CONFIG: resolveWorkingPath(`${CYBERSKILL_DIRECTORY}/config/storybook/storybook.preview.js`),\n DOT_AGENT: resolveWorkingPath(DOT_AGENT),\n};\n\n/**\n * Creates Git hooks configuration based on whether this is the current project.\n * This function generates a configuration object for Git hooks that includes\n * pre-commit and commit-msg hooks, with an optional pre-push hook for the current project.\n *\n * @param context - Context object containing project information.\n * @param context.isCurrentProject - Whether this is the current project being worked on.\n * @returns A Git hooks configuration object with appropriate commands for each hook.\n */\nexport function createGitHooksConfig({ isCurrentProject }: Partial<I_CommandContext>) {\n return {\n 'pre-commit': LINT_STAGED_CLI,\n 'commit-msg': COMMIT_LINT_CLI,\n ...(isCurrentProject ? { 'pre-push': rawCommand(`${GIT_CLI} pull`) } : { 'pre-push': rawCommand(`TAG_ONLY=true; while read local_ref local_oid remote_ref remote_oid; do case \\\"$local_ref\\\" in refs/tags/*) ;; *) TAG_ONLY=false; break ;; esac; done; if [ \\\"$TAG_ONLY\\\" = true ]; then echo '[pre-push] Tag-only push, skipping build.'; exit 0; fi; ${PNPM_CLI} build`) }),\n };\n}\n\n/**\n * Builds a command function based on the specified type and configuration.\n * This function creates a command executor that handles different command types\n * including CLI commands and string commands. It manages package dependencies\n * and formats commands appropriately for execution.\n *\n * The function supports:\n * - CLI commands that require package installation\n * - String commands that are executed directly\n * - Automatic package dependency management\n * - Command formatting and validation\n *\n * @param config - Configuration object containing type, packages, and command properties.\n * @param config.type - The type of command to build (CLI or STRING).\n * @param config.packages - Optional array of packages required for CLI commands.\n * @param config.command - The command string to execute.\n * @returns A function that returns a promise resolving to the formatted command string.\n * @throws {Error} When an unsupported command type is provided.\n */\nfunction buildCommand({ type, packages, command }: { type: E_CommandType; packages?: I_PackageInput[]; command: string }): () => Promise<string> {\n const uniquePackages = packages?.reduce((acc: I_PackageInput[], pkg) => {\n if (!acc.some(existingPkg => existingPkg.name === pkg.name)) {\n acc.push(pkg);\n }\n return acc;\n }, []);\n\n return async () => {\n switch (type) {\n case E_CommandType.CLI: {\n if (uniquePackages?.length) {\n await setupPackages(uniquePackages, {\n install: true,\n });\n }\n\n return formatCommand(rawCommand(`${PNPM_EXEC_CLI} ${command}`)) as string;\n }\n case E_CommandType.STRING: {\n return formatCommand(rawCommand(command)) as string;\n }\n default: {\n throw new Error('Unsupported command type');\n }\n }\n };\n}\n\nconst RE_MIGRATE_NAME = /^[\\w-]+$/;\n\nexport const command = {\n simpleGitHooks: buildCommand({\n type: E_CommandType.CLI,\n packages: [\n {\n name: SIMPLE_GIT_HOOKS_PACKAGE_NAME,\n type: E_PackageType.DEV_DEPENDENCY,\n },\n\n ],\n command: SIMPLE_GIT_HOOK_CLI,\n }),\n eslintInspect: buildCommand({\n type: E_CommandType.CLI,\n packages: [\n {\n name:\n ESLINT_INSPECT_PACKAGE_NAME,\n type: E_PackageType.DEV_DEPENDENCY,\n },\n\n ],\n command: ESLINT_INSPECT_CLI,\n }),\n nodeModulesInspect: buildCommand({\n type: E_CommandType.CLI,\n packages: [\n {\n name: NODE_MODULES_INSPECT_PACKAGE_NAME,\n type: E_PackageType.DEV_DEPENDENCY,\n },\n\n ],\n command: NODE_MODULES_INSPECT_CLI,\n }),\n eslintCheck: buildCommand({\n type: E_CommandType.CLI,\n packages: [\n {\n name: ESLINT_PACKAGE_NAME,\n type: E_PackageType.DEV_DEPENDENCY,\n },\n\n ],\n command: `${ESLINT_CLI} ${PATH.WORKING_DIRECTORY} --no-cache`,\n }),\n eslintFix: buildCommand({\n type: E_CommandType.CLI,\n packages: [\n {\n name: ESLINT_PACKAGE_NAME,\n type: E_PackageType.DEV_DEPENDENCY,\n },\n\n ],\n command: `${ESLINT_CLI} ${PATH.WORKING_DIRECTORY} --fix --no-cache`,\n }),\n typescriptCheck: buildCommand({\n type: E_CommandType.CLI,\n packages: [\n {\n name: TSC_PACKAGE_NAME,\n type: E_PackageType.DEV_DEPENDENCY,\n },\n\n ],\n command: `${TSC_CLI} -p ${PATH.TS_CONFIG} --noEmit`,\n }),\n testUnit: buildCommand({\n type: E_CommandType.CLI,\n packages: [\n {\n name: VITEST_PACKAGE_NAME,\n type: E_PackageType.DEV_DEPENDENCY,\n },\n ],\n command: `${VITEST_CLI} --config ${PATH.VITEST_UNIT_CONFIG}`,\n }),\n testE2e: buildCommand({\n type: E_CommandType.CLI,\n packages: [\n {\n name: VITEST_PACKAGE_NAME,\n type: E_PackageType.DEV_DEPENDENCY,\n },\n ],\n command: `${VITEST_CLI} --config ${PATH.VITEST_E2E_CONFIG}`,\n }),\n mongoMigrateCreate: (migrateName: string) => {\n if (!RE_MIGRATE_NAME.test(migrateName)) {\n throw new Error('Migration name must only contain alphanumeric characters, underscores, and hyphens.');\n }\n\n return buildCommand({\n type: E_CommandType.CLI,\n packages: [\n {\n name: TSX_CLI,\n type: E_PackageType.DEPENDENCY,\n },\n {\n name: MIGRATE_MONGO_PACKAGE_NAME,\n type: E_PackageType.DEPENDENCY,\n },\n ],\n command: `${TSX_CLI} ${MIGRATE_MONGO_CLI} create ${migrateName} -f ${PATH.MIGRATE_MONGO_CONFIG}`,\n })();\n },\n mongoMigrateUp: buildCommand({\n type: E_CommandType.CLI,\n packages: [\n {\n name: TSX_CLI,\n type: E_PackageType.DEPENDENCY,\n },\n {\n name: MIGRATE_MONGO_PACKAGE_NAME,\n type: E_PackageType.DEPENDENCY,\n },\n ],\n command: `${TSX_CLI} ${MIGRATE_MONGO_CLI} up -f ${PATH.MIGRATE_MONGO_CONFIG}`,\n }),\n mongoMigrateDown: buildCommand({\n type: E_CommandType.CLI,\n packages: [\n {\n name: TSX_CLI,\n type: E_PackageType.DEPENDENCY,\n },\n {\n name: MIGRATE_MONGO_PACKAGE_NAME,\n type: E_PackageType.DEPENDENCY,\n },\n ],\n command: `${TSX_CLI} ${MIGRATE_MONGO_CLI} down -f ${PATH.MIGRATE_MONGO_CONFIG}`,\n }),\n commitLint: buildCommand({\n type: E_CommandType.CLI,\n packages: [\n {\n name: COMMIT_LINT_PACKAGE_NAME,\n type: E_PackageType.DEV_DEPENDENCY,\n },\n {\n name: COMMIT_LINT_CONVENTIONAL_CONFIG_PACKAGE_NAME,\n type: E_PackageType.DEV_DEPENDENCY,\n },\n ],\n command: `${COMMIT_LINT_CLI} --edit ${PATH.GIT_COMMIT_MSG} --config ${PATH.COMMITLINT_CONFIG}`,\n }),\n lintStaged: buildCommand({\n type: E_CommandType.CLI,\n packages: [\n {\n name: LINT_STAGED_PACKAGE_NAME,\n type: E_PackageType.DEV_DEPENDENCY,\n },\n ],\n command: `${LINT_STAGED_CLI} --config ${PATH.LINT_STAGED_CONFIG}`,\n }),\n configureGitHook: buildCommand({\n type: E_CommandType.STRING,\n command: `${GIT_CLI} config core.hooksPath ${PATH.GIT_HOOK}`,\n }),\n build: buildCommand({\n type: E_CommandType.STRING,\n command: `${PNPM_CLI} run --if-present build`,\n }),\n pnpmInstallStandard: buildCommand({\n type: E_CommandType.STRING,\n command: `${PNPM_CLI} install --ignore-scripts`,\n }),\n pnpmInstallLegacy: buildCommand({\n type: E_CommandType.STRING,\n command: `${PNPM_CLI} install --ignore-scripts --legacy-peer-deps`,\n }),\n pnpmInstallForce: buildCommand({\n type: E_CommandType.STRING,\n command: `${PNPM_CLI} install --ignore-scripts --force`,\n }),\n pnpmPruneStore: buildCommand({\n type: E_CommandType.STRING,\n command: `${PNPM_CLI} store prune`,\n }),\n pnpmCleanCache: buildCommand({\n type: E_CommandType.STRING,\n command: `${PNPM_CLI} cache delete`,\n }),\n storybookDev: buildCommand({\n type: E_CommandType.CLI,\n packages: [\n {\n name: STORYBOOK_PACKAGE_NAME,\n type: E_PackageType.DEV_DEPENDENCY,\n },\n ],\n command: `${STORYBOOK_CLI} dev`,\n }),\n storybookBuild: buildCommand({\n type: E_CommandType.CLI,\n packages: [\n {\n name: STORYBOOK_PACKAGE_NAME,\n type: E_PackageType.DEV_DEPENDENCY,\n },\n ],\n command: `${STORYBOOK_CLI} build`,\n }),\n};\n"],"mappings":";;;;;;;AAaA,IAAa,IAFD,GAAQ,CAEiB,KACxB,IAA0B,sBAC1B,IAAe,gBACf,IAAkB,QAClB,IAAmB,UACnB,IAAe,gBACf,IAAoB,qBACpB,IAAgB,iBAChB,IAAa,cACb,IAAuB,0BACvB,IAAiB,kBACjB,IAAW,eACX,IAAqB,uBACrB,IAAc,qBACd,IAAuB,4BACvB,IACW,GAAQ,aAAa,EAAA,eAAgC,CAAC,CAExC,SAAA,uBAC5B,EAAK,GAAmB,EAAgB,GACxC,EAAK,GAAmB,GAAc,GAAyB,EAAgB,EAI5E,IAAiB,cACjB,IAAsB,yBACtB,IAAsB,UACtB,IAAa,UACb,IAAsB,UACtB,IAAa,UACb,IAA2B,mBAC3B,IAA+C,mCAC/C,IAAkB,cAClB,IAA2B,eAC3B,IAAkB,eAClB,IAAmB,cACnB,IAAU,OACV,IAAU,OACV,IAAU,OACV,IAAW,QACX,IAAgB,aAChB,IAAgC,oBAChC,IAAsB,oBACtB,IAA8B,4BAC9B,IAAqB,2BACrB,IAAoC,0BACpC,IAA2B,0BAC3B,IAA6B,iBAC7B,IAAoB,kDACpB,IAAyB,aACzB,IAAgB,aAChB,IAAsB,kBACtB,IAAY,UAEZ,IAAO;CAChB;CACA;CACA,kBAAkB,EAAmB,EAAiB;CACtD,WAAW,EAAmB,EAAc;CAC5C,YAAY,EAAmB,EAAW;CAC1C,UAAU,EAAmB,EAAS;CACtC,gBAAgB,EAAmB,EAAmB;CACtD,aAAa,EAAmB,EAAY;CAC5C,uBAAuB,EAAmB,EAAqB;CAC/D,cAAc,EAAmB,EAAa;CAC9C,mBAAmB,EAAmB,EAAkB;CACxD,gBAAgB,EAAmB,EAAe;CAClD,cAAc,EAAmB,EAAa;CAC9C,sBAAsB,EAAmB,EAAqB;CAC9D,oBAAoB,EAAmB,GAAG,EAAqB,8BAA8B;CAC7F,mBAAmB,EAAmB,GAAG,EAAqB,6BAA6B;CAC3F,oBAAoB,EAAmB,GAAG,EAAqB,+BAA+B;CAC9F,mBAAmB,EAAmB,GAAG,EAAqB,8BAA8B;CAC5F,uBAAuB,EAAmB,GAAG,EAAqB,qCAAqC;CACvG,0BAA0B,EAAmB,GAAG,EAAqB,wCAAwC;CAC7G,WAAW,EAAmB,EAAU;CAC3C;AAWD,SAAgB,GAAqB,EAAE,uBAA+C;AAClF,QAAO;EACH,cAAc;EACd,cAAc;EACd,GAAI,IAAmB,EAAE,YAAY,EAAW,WAAkB,EAAE,GAAG,EAAE,YAAY,EAAW,0PAA0P,EAAS,QAAQ,EAAE;EAChX;;AAsBL,SAAS,EAAa,EAAE,SAAM,aAAU,cAAyG;CAC7I,IAAM,IAAiB,GAAU,QAAQ,GAAuB,OACvD,EAAI,MAAK,MAAe,EAAY,SAAS,EAAI,KAAK,IACvD,EAAI,KAAK,EAAI,EAEV,IACR,EAAE,CAAC;AAEN,QAAO,YAAY;AACf,UAAQ,GAAR;GACI,KAAK,EAAc,IAOf,QANI,GAAgB,UAChB,MAAM,GAAc,GAAgB,EAChC,SAAS,IACZ,CAAC,EAGC,EAAc,EAAW,GAAG,EAAc,GAAG,IAAU,CAAC;GAEnE,KAAK,EAAc,OACf,QAAO,EAAc,EAAW,EAAQ,CAAC;GAE7C,QACI,OAAU,MAAM,2BAA2B;;;;AAM3D,IAAM,KAAkB,YAEX,KAAU;CACnB,gBAAgB,EAAa;EACzB,MAAM,EAAc;EACpB,UAAU,CACN;GACI,MAAM;GACN,MAAM,EAAc;GACvB,CAEJ;EACD,SAAS;EACZ,CAAC;CACF,eAAe,EAAa;EACxB,MAAM,EAAc;EACpB,UAAU,CACN;GACI,MACI;GACJ,MAAM,EAAc;GACvB,CAEJ;EACD,SAAS;EACZ,CAAC;CACF,oBAAoB,EAAa;EAC7B,MAAM,EAAc;EACpB,UAAU,CACN;GACI,MAAM;GACN,MAAM,EAAc;GACvB,CAEJ;EACD,SAAS;EACZ,CAAC;CACF,aAAa,EAAa;EACtB,MAAM,EAAc;EACpB,UAAU,CACN;GACI,MAAM;GACN,MAAM,EAAc;GACvB,CAEJ;EACD,SAAS,GAAG,EAAW,GAAG,EAAK,kBAAkB;EACpD,CAAC;CACF,WAAW,EAAa;EACpB,MAAM,EAAc;EACpB,UAAU,CACN;GACI,MAAM;GACN,MAAM,EAAc;GACvB,CAEJ;EACD,SAAS,GAAG,EAAW,GAAG,EAAK,kBAAkB;EACpD,CAAC;CACF,iBAAiB,EAAa;EAC1B,MAAM,EAAc;EACpB,UAAU,CACN;GACI,MAAM;GACN,MAAM,EAAc;GACvB,CAEJ;EACD,SAAS,UAAiB,EAAK,UAAU;EAC5C,CAAC;CACF,UAAU,EAAa;EACnB,MAAM,EAAc;EACpB,UAAU,CACN;GACI,MAAM;GACN,MAAM,EAAc;GACvB,CACJ;EACD,SAAS,GAAG,EAAW,YAAY,EAAK;EAC3C,CAAC;CACF,SAAS,EAAa;EAClB,MAAM,EAAc;EACpB,UAAU,CACN;GACI,MAAM;GACN,MAAM,EAAc;GACvB,CACJ;EACD,SAAS,GAAG,EAAW,YAAY,EAAK;EAC3C,CAAC;CACF,qBAAqB,MAAwB;AACzC,MAAI,CAAC,GAAgB,KAAK,EAAY,CAClC,OAAU,MAAM,sFAAsF;AAG1G,SAAO,EAAa;GAChB,MAAM,EAAc;GACpB,UAAU,CACN;IACI,MAAA;IACA,MAAM,EAAc;IACvB,EACD;IACI,MAAM;IACN,MAAM,EAAc;IACvB,CACJ;GACD,SAAS,OAAc,EAAkB,UAAU,EAAY,MAAM,EAAK;GAC7E,CAAC,EAAE;;CAER,gBAAgB,EAAa;EACzB,MAAM,EAAc;EACpB,UAAU,CACN;GACI,MAAA;GACA,MAAM,EAAc;GACvB,EACD;GACI,MAAM;GACN,MAAM,EAAc;GACvB,CACJ;EACD,SAAS,OAAc,EAAkB,SAAS,EAAK;EAC1D,CAAC;CACF,kBAAkB,EAAa;EAC3B,MAAM,EAAc;EACpB,UAAU,CACN;GACI,MAAA;GACA,MAAM,EAAc;GACvB,EACD;GACI,MAAM;GACN,MAAM,EAAc;GACvB,CACJ;EACD,SAAS,OAAc,EAAkB,WAAW,EAAK;EAC5D,CAAC;CACF,YAAY,EAAa;EACrB,MAAM,EAAc;EACpB,UAAU,CACN;GACI,MAAM;GACN,MAAM,EAAc;GACvB,EACD;GACI,MAAM;GACN,MAAM,EAAc;GACvB,CACJ;EACD,SAAS,GAAG,EAAgB,UAAU,EAAK,eAAe,YAAY,EAAK;EAC9E,CAAC;CACF,YAAY,EAAa;EACrB,MAAM,EAAc;EACpB,UAAU,CACN;GACI,MAAM;GACN,MAAM,EAAc;GACvB,CACJ;EACD,SAAS,GAAG,EAAgB,YAAY,EAAK;EAChD,CAAC;CACF,kBAAkB,EAAa;EAC3B,MAAM,EAAc;EACpB,SAAS,6BAAoC,EAAK;EACrD,CAAC;CACF,OAAO,EAAa;EAChB,MAAM,EAAc;EACpB,SAAS,GAAG,EAAS;EACxB,CAAC;CACF,qBAAqB,EAAa;EAC9B,MAAM,EAAc;EACpB,SAAS,GAAG,EAAS;EACxB,CAAC;CACF,mBAAmB,EAAa;EAC5B,MAAM,EAAc;EACpB,SAAS,GAAG,EAAS;EACxB,CAAC;CACF,kBAAkB,EAAa;EAC3B,MAAM,EAAc;EACpB,SAAS,GAAG,EAAS;EACxB,CAAC;CACF,gBAAgB,EAAa;EACzB,MAAM,EAAc;EACpB,SAAS,GAAG,EAAS;EACxB,CAAC;CACF,gBAAgB,EAAa;EACzB,MAAM,EAAc;EACpB,SAAS,GAAG,EAAS;EACxB,CAAC;CACF,cAAc,EAAa;EACvB,MAAM,EAAc;EACpB,UAAU,CACN;GACI,MAAM;GACN,MAAM,EAAc;GACvB,CACJ;EACD,SAAS,GAAG,EAAc;EAC7B,CAAC;CACF,gBAAgB,EAAa;EACzB,MAAM,EAAc;EACpB,UAAU,CACN;GACI,MAAM;GACN,MAAM,EAAc;GACvB,CACJ;EACD,SAAS,GAAG,EAAc;EAC7B,CAAC;CACL"}
|
|
1
|
+
{"version":3,"file":"path.constant.js","names":[],"sources":["../../../src/node/path/path.constant.ts"],"sourcesContent":["import fsExtra from 'fs-extra';\n\nimport { getEnv } from '#config/env/index.js';\n\nimport type { I_PackageInput, I_PackageJson } from '../package/index.js';\n\nimport { E_CommandType, formatCommand, rawCommand } from '../command/index.js';\nimport { E_PackageType, setupPackages } from '../package/index.js';\nimport { join, resolveWorkingPath } from './path.util.js';\n\nconst env = getEnv();\n\nexport const WORKING_DIRECTORY = env.CWD;\nexport const CYBERSKILL_PACKAGE_NAME = '@cyberskill/shared';\nexport const NODE_MODULES = 'node_modules';\nexport const BUILD_DIRECTORY = 'dist';\nexport const PUBLIC_DIRECTORY = 'public';\nexport const PACKAGE_JSON = 'package.json';\nexport const PACKAGE_LOCK_JSON = 'package-lock.json';\nexport const TSCONFIG_JSON = 'tsconfig.json';\nexport const GIT_IGNORE = '.gitignore';\nexport const SIMPLE_GIT_HOOK_JSON = '.simple-git-hooks.json';\nexport const PNPM_LOCK_YAML = 'pnpm-lock.yaml';\nexport const GIT_HOOK = '.git/hooks/';\nexport const GIT_COMMIT_EDITMSG = '.git/COMMIT_EDITMSG';\nexport const GIT_EXCLUDE = '.git/info/exclude';\nexport const MIGRATE_MONGO_CONFIG = '.migrate-mongo.config.js';\nexport const CYBERSKILL_DIRECTORY = (() => {\n try {\n const packageJson = fsExtra.readJsonSync(resolveWorkingPath(PACKAGE_JSON)) as I_PackageJson;\n\n const baseDirectory = packageJson.name === CYBERSKILL_PACKAGE_NAME\n ? join(WORKING_DIRECTORY, BUILD_DIRECTORY)\n : join(WORKING_DIRECTORY, NODE_MODULES, CYBERSKILL_PACKAGE_NAME, BUILD_DIRECTORY);\n\n return baseDirectory;\n }\n catch {\n return join(WORKING_DIRECTORY, NODE_MODULES, CYBERSKILL_PACKAGE_NAME, BUILD_DIRECTORY);\n }\n})();\nexport const CYBERSKILL_CLI = 'cyberskill';\nexport const CYBERSKILL_CLI_PATH = 'src/node/cli/index.ts';\nexport const ESLINT_PACKAGE_NAME = 'eslint';\nexport const ESLINT_CLI = 'eslint';\nexport const VITEST_PACKAGE_NAME = 'vitest';\nexport const VITEST_CLI = 'vitest';\nexport const COMMIT_LINT_PACKAGE_NAME = '@commitlint/cli';\nexport const COMMIT_LINT_CONVENTIONAL_CONFIG_PACKAGE_NAME = '@commitlint/config-conventional';\nexport const COMMIT_LINT_CLI = 'commitlint';\nexport const LINT_STAGED_PACKAGE_NAME = 'lint-staged';\nexport const LINT_STAGED_CLI = 'lint-staged';\nexport const TSC_PACKAGE_NAME = 'typescript';\nexport const TSC_CLI = 'tsc';\nexport const TSX_CLI = 'tsx';\nexport const GIT_CLI = 'git';\nexport const PNPM_CLI = 'pnpm';\nexport const PNPM_EXEC_CLI = 'pnpm exec';\nexport const SIMPLE_GIT_HOOKS_PACKAGE_NAME = 'simple-git-hooks';\nexport const SIMPLE_GIT_HOOK_CLI = 'simple-git-hooks';\nexport const ESLINT_INSPECT_PACKAGE_NAME = '@eslint/config-inspector';\nexport const ESLINT_INSPECT_CLI = 'eslint-config-inspector';\nexport const NODE_MODULES_INSPECT_PACKAGE_NAME = 'node-modules-inspector';\nexport const NODE_MODULES_INSPECT_CLI = 'node-modules-inspector';\nexport const MIGRATE_MONGO_PACKAGE_NAME = 'migrate-mongo';\nexport const MIGRATE_MONGO_CLI = './node_modules/migrate-mongo/bin/migrate-mongo';\nexport const STORYBOOK_PACKAGE_NAME = 'storybook';\nexport const STORYBOOK_CLI = 'storybook';\nexport const AG_KIT_PACKAGE_NAME = '@vudovn/ag-kit';\nexport const DOT_AGENT = '.agent';\n\nexport const PATH = {\n CYBERSKILL_DIRECTORY,\n WORKING_DIRECTORY,\n PUBLIC_DIRECTORY: resolveWorkingPath(PUBLIC_DIRECTORY),\n TS_CONFIG: resolveWorkingPath(TSCONFIG_JSON),\n GIT_IGNORE: resolveWorkingPath(GIT_IGNORE),\n GIT_HOOK: resolveWorkingPath(GIT_HOOK),\n GIT_COMMIT_MSG: resolveWorkingPath(GIT_COMMIT_EDITMSG),\n GIT_EXCLUDE: resolveWorkingPath(GIT_EXCLUDE),\n SIMPLE_GIT_HOOKS_JSON: resolveWorkingPath(SIMPLE_GIT_HOOK_JSON),\n PACKAGE_JSON: resolveWorkingPath(PACKAGE_JSON),\n PACKAGE_LOCK_JSON: resolveWorkingPath(PACKAGE_LOCK_JSON),\n PNPM_LOCK_YAML: resolveWorkingPath(PNPM_LOCK_YAML),\n NODE_MODULES: resolveWorkingPath(NODE_MODULES),\n MIGRATE_MONGO_CONFIG: resolveWorkingPath(MIGRATE_MONGO_CONFIG),\n LINT_STAGED_CONFIG: resolveWorkingPath(`${CYBERSKILL_DIRECTORY}/config/lint-staged/index.js`),\n COMMITLINT_CONFIG: resolveWorkingPath(`${CYBERSKILL_DIRECTORY}/config/commitlint/index.js`),\n VITEST_UNIT_CONFIG: resolveWorkingPath(`${CYBERSKILL_DIRECTORY}/config/vitest/vitest.unit.js`),\n VITEST_E2E_CONFIG: resolveWorkingPath(`${CYBERSKILL_DIRECTORY}/config/vitest/vitest.e2e.js`),\n STORYBOOK_MAIN_CONFIG: resolveWorkingPath(`${CYBERSKILL_DIRECTORY}/config/storybook/storybook.main.js`),\n STORYBOOK_PREVIEW_CONFIG: resolveWorkingPath(`${CYBERSKILL_DIRECTORY}/config/storybook/storybook.preview.js`),\n DOT_AGENT: resolveWorkingPath(DOT_AGENT),\n};\n\n/**\n * Creates Git hooks configuration based on whether this is the current project.\n * This function generates a configuration object for Git hooks that includes\n * pre-commit and commit-msg hooks, with an optional pre-push hook for the current project.\n *\n * @returns A Git hooks configuration object with appropriate commands for each hook.\n */\nexport function createGitHooksConfig() {\n return {\n 'pre-commit': LINT_STAGED_CLI,\n 'commit-msg': COMMIT_LINT_CLI,\n 'pre-push': rawCommand(`${GIT_CLI} pull && ${PNPM_CLI} test`),\n };\n}\n\n/**\n * Builds a command function based on the specified type and configuration.\n * This function creates a command executor that handles different command types\n * including CLI commands and string commands. It manages package dependencies\n * and formats commands appropriately for execution.\n *\n * The function supports:\n * - CLI commands that require package installation\n * - String commands that are executed directly\n * - Automatic package dependency management\n * - Command formatting and validation\n *\n * @param config - Configuration object containing type, packages, and command properties.\n * @param config.type - The type of command to build (CLI or STRING).\n * @param config.packages - Optional array of packages required for CLI commands.\n * @param config.command - The command string to execute.\n * @returns A function that returns a promise resolving to the formatted command string.\n * @throws {Error} When an unsupported command type is provided.\n */\nfunction buildCommand({ type, packages, command }: { type: E_CommandType; packages?: I_PackageInput[]; command: string }): () => Promise<string> {\n const uniquePackages = packages?.reduce((acc: I_PackageInput[], pkg) => {\n if (!acc.some(existingPkg => existingPkg.name === pkg.name)) {\n acc.push(pkg);\n }\n return acc;\n }, []);\n\n return async () => {\n switch (type) {\n case E_CommandType.CLI: {\n if (uniquePackages?.length) {\n await setupPackages(uniquePackages, {\n install: true,\n });\n }\n\n return formatCommand(rawCommand(`${PNPM_EXEC_CLI} ${command}`)) as string;\n }\n case E_CommandType.STRING: {\n return formatCommand(rawCommand(command)) as string;\n }\n default: {\n throw new Error('Unsupported command type');\n }\n }\n };\n}\n\nconst RE_MIGRATE_NAME = /^[\\w-]+$/;\n\nexport const command = {\n simpleGitHooks: buildCommand({\n type: E_CommandType.CLI,\n packages: [\n {\n name: SIMPLE_GIT_HOOKS_PACKAGE_NAME,\n type: E_PackageType.DEV_DEPENDENCY,\n },\n\n ],\n command: SIMPLE_GIT_HOOK_CLI,\n }),\n eslintInspect: buildCommand({\n type: E_CommandType.CLI,\n packages: [\n {\n name:\n ESLINT_INSPECT_PACKAGE_NAME,\n type: E_PackageType.DEV_DEPENDENCY,\n },\n\n ],\n command: ESLINT_INSPECT_CLI,\n }),\n nodeModulesInspect: buildCommand({\n type: E_CommandType.CLI,\n packages: [\n {\n name: NODE_MODULES_INSPECT_PACKAGE_NAME,\n type: E_PackageType.DEV_DEPENDENCY,\n },\n\n ],\n command: NODE_MODULES_INSPECT_CLI,\n }),\n eslintCheck: buildCommand({\n type: E_CommandType.CLI,\n packages: [\n {\n name: ESLINT_PACKAGE_NAME,\n type: E_PackageType.DEV_DEPENDENCY,\n },\n\n ],\n command: `${ESLINT_CLI} ${PATH.WORKING_DIRECTORY} --no-cache`,\n }),\n eslintFix: buildCommand({\n type: E_CommandType.CLI,\n packages: [\n {\n name: ESLINT_PACKAGE_NAME,\n type: E_PackageType.DEV_DEPENDENCY,\n },\n\n ],\n command: `${ESLINT_CLI} ${PATH.WORKING_DIRECTORY} --fix --no-cache`,\n }),\n typescriptCheck: buildCommand({\n type: E_CommandType.CLI,\n packages: [\n {\n name: TSC_PACKAGE_NAME,\n type: E_PackageType.DEV_DEPENDENCY,\n },\n\n ],\n command: `${TSC_CLI} -p ${PATH.TS_CONFIG} --noEmit`,\n }),\n testUnit: buildCommand({\n type: E_CommandType.CLI,\n packages: [\n {\n name: VITEST_PACKAGE_NAME,\n type: E_PackageType.DEV_DEPENDENCY,\n },\n ],\n command: `${VITEST_CLI} --config ${PATH.VITEST_UNIT_CONFIG}`,\n }),\n testE2e: buildCommand({\n type: E_CommandType.CLI,\n packages: [\n {\n name: VITEST_PACKAGE_NAME,\n type: E_PackageType.DEV_DEPENDENCY,\n },\n ],\n command: `${VITEST_CLI} --config ${PATH.VITEST_E2E_CONFIG}`,\n }),\n mongoMigrateCreate: (migrateName: string) => {\n if (!RE_MIGRATE_NAME.test(migrateName)) {\n throw new Error('Migration name must only contain alphanumeric characters, underscores, and hyphens.');\n }\n\n return buildCommand({\n type: E_CommandType.CLI,\n packages: [\n {\n name: TSX_CLI,\n type: E_PackageType.DEPENDENCY,\n },\n {\n name: MIGRATE_MONGO_PACKAGE_NAME,\n type: E_PackageType.DEPENDENCY,\n },\n ],\n command: `${TSX_CLI} ${MIGRATE_MONGO_CLI} create ${migrateName} -f ${PATH.MIGRATE_MONGO_CONFIG}`,\n })();\n },\n mongoMigrateUp: buildCommand({\n type: E_CommandType.CLI,\n packages: [\n {\n name: TSX_CLI,\n type: E_PackageType.DEPENDENCY,\n },\n {\n name: MIGRATE_MONGO_PACKAGE_NAME,\n type: E_PackageType.DEPENDENCY,\n },\n ],\n command: `${TSX_CLI} ${MIGRATE_MONGO_CLI} up -f ${PATH.MIGRATE_MONGO_CONFIG}`,\n }),\n mongoMigrateDown: buildCommand({\n type: E_CommandType.CLI,\n packages: [\n {\n name: TSX_CLI,\n type: E_PackageType.DEPENDENCY,\n },\n {\n name: MIGRATE_MONGO_PACKAGE_NAME,\n type: E_PackageType.DEPENDENCY,\n },\n ],\n command: `${TSX_CLI} ${MIGRATE_MONGO_CLI} down -f ${PATH.MIGRATE_MONGO_CONFIG}`,\n }),\n commitLint: buildCommand({\n type: E_CommandType.CLI,\n packages: [\n {\n name: COMMIT_LINT_PACKAGE_NAME,\n type: E_PackageType.DEV_DEPENDENCY,\n },\n {\n name: COMMIT_LINT_CONVENTIONAL_CONFIG_PACKAGE_NAME,\n type: E_PackageType.DEV_DEPENDENCY,\n },\n ],\n command: `${COMMIT_LINT_CLI} --edit ${PATH.GIT_COMMIT_MSG} --config ${PATH.COMMITLINT_CONFIG}`,\n }),\n lintStaged: buildCommand({\n type: E_CommandType.CLI,\n packages: [\n {\n name: LINT_STAGED_PACKAGE_NAME,\n type: E_PackageType.DEV_DEPENDENCY,\n },\n ],\n command: `${LINT_STAGED_CLI} --config ${PATH.LINT_STAGED_CONFIG}`,\n }),\n configureGitHook: buildCommand({\n type: E_CommandType.STRING,\n command: `${GIT_CLI} config core.hooksPath ${PATH.GIT_HOOK}`,\n }),\n build: buildCommand({\n type: E_CommandType.STRING,\n command: `${PNPM_CLI} run --if-present build`,\n }),\n pnpmInstallStandard: buildCommand({\n type: E_CommandType.STRING,\n command: `${PNPM_CLI} install --ignore-scripts`,\n }),\n pnpmInstallLegacy: buildCommand({\n type: E_CommandType.STRING,\n command: `${PNPM_CLI} install --ignore-scripts --legacy-peer-deps`,\n }),\n pnpmInstallForce: buildCommand({\n type: E_CommandType.STRING,\n command: `${PNPM_CLI} install --ignore-scripts --force`,\n }),\n pnpmPruneStore: buildCommand({\n type: E_CommandType.STRING,\n command: `${PNPM_CLI} store prune`,\n }),\n pnpmCleanCache: buildCommand({\n type: E_CommandType.STRING,\n command: `${PNPM_CLI} cache delete`,\n }),\n storybookDev: buildCommand({\n type: E_CommandType.CLI,\n packages: [\n {\n name: STORYBOOK_PACKAGE_NAME,\n type: E_PackageType.DEV_DEPENDENCY,\n },\n ],\n command: `${STORYBOOK_CLI} dev`,\n }),\n storybookBuild: buildCommand({\n type: E_CommandType.CLI,\n packages: [\n {\n name: STORYBOOK_PACKAGE_NAME,\n type: E_PackageType.DEV_DEPENDENCY,\n },\n ],\n command: `${STORYBOOK_CLI} build`,\n }),\n};\n"],"mappings":"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"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { NODE_FS_DRIVER_NAME as e, STORAGE_INSTANCE_NAME as t, STORAGE_KEY_EXTENSION as n, STORAGE_STORE_NAME as r } from "./storage.constant.js";
|
|
2
|
-
import {
|
|
3
|
-
export { e as NODE_FS_DRIVER_NAME, t as STORAGE_INSTANCE_NAME, n as STORAGE_KEY_EXTENSION, r as STORAGE_STORE_NAME, i as storage };
|
|
2
|
+
import { resetStorageForTesting as i, storage as a } from "./storage.util.js";
|
|
3
|
+
export { e as NODE_FS_DRIVER_NAME, t as STORAGE_INSTANCE_NAME, n as STORAGE_KEY_EXTENSION, r as STORAGE_STORE_NAME, i as resetStorageForTesting, a as storage };
|
|
@@ -49,3 +49,9 @@ export declare const storage: {
|
|
|
49
49
|
*/
|
|
50
50
|
getLogLink(key: string): Promise<string | null>;
|
|
51
51
|
};
|
|
52
|
+
/**
|
|
53
|
+
* Resets all module-level singleton state used by the storage module.
|
|
54
|
+
* Intended for use in tests to ensure isolation between test cases.
|
|
55
|
+
* Do NOT call this in production code.
|
|
56
|
+
*/
|
|
57
|
+
export declare function resetStorageForTesting(): void;
|
|
@@ -126,7 +126,10 @@ var v = {
|
|
|
126
126
|
}
|
|
127
127
|
}
|
|
128
128
|
};
|
|
129
|
+
function y() {
|
|
130
|
+
h = null, g = null, u.baseDir = "";
|
|
131
|
+
}
|
|
129
132
|
//#endregion
|
|
130
|
-
export { v as storage };
|
|
133
|
+
export { y as resetStorageForTesting, v as storage };
|
|
131
134
|
|
|
132
135
|
//# sourceMappingURL=storage.util.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"storage.util.js","names":[],"sources":["../../../src/node/storage/storage.util.ts"],"sourcesContent":["import localForage from 'localforage';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\n\nimport { getEnv } from '#config/env/index.js';\n\nimport type { LocalForageDriver, NodeFsDriverState, NodeLocalForageOptions } from './storage.type.js';\n\nimport { catchError, log } from '../log/index.js';\nimport { NODE_FS_DRIVER_NAME, STORAGE_INSTANCE_NAME, STORAGE_KEY_EXTENSION, STORAGE_STORE_NAME } from './storage.constant.js';\n\nconst nodeFsDriverState: NodeFsDriverState = {\n baseDir: '',\n};\n\n/**\n * Encodes a storage key into a filename-safe string.\n */\nfunction encodeKey(key: string): string {\n return `${encodeURIComponent(key)}${STORAGE_KEY_EXTENSION}`;\n}\n\n/**\n * Decodes a filename-safe key back to the original storage key.\n */\nfunction decodeKey(fileName: string): string {\n return decodeURIComponent(fileName.slice(0, -STORAGE_KEY_EXTENSION.length));\n}\n\n/**\n * Maps a storage key to an absolute file path inside the storage directory.\n */\nfunction getFilePath(key: string, baseDir: string): string {\n return path.join(baseDir, encodeKey(key));\n}\n\n/**\n * Custom localForage driver that stores JSON-encoded values on the filesystem.\n */\nconst nodeFsDriver: LocalForageDriver = {\n _driver: NODE_FS_DRIVER_NAME,\n _support: true,\n /** Ensures the storage directory exists and respects custom baseDir overrides. */\n async _initStorage(options: unknown) {\n try {\n const baseDirFromOptions = typeof options === 'object' && options !== null && 'baseDir' in options\n ? (options as { baseDir?: unknown }).baseDir\n : undefined;\n\n if (typeof baseDirFromOptions === 'string' && baseDirFromOptions.length > 0) {\n nodeFsDriverState.baseDir = baseDirFromOptions;\n }\n else {\n nodeFsDriverState.baseDir = getEnv().CYBERSKILL_STORAGE_DIRECTORY;\n }\n\n await fs.mkdir(nodeFsDriverState.baseDir, { recursive: true });\n }\n catch (error) {\n log.error('[Storage:init]', error);\n throw error;\n }\n },\n /** Deletes all stored entries by recreating the directory. Callers must ensure no concurrent operations. */\n async clear() {\n const { baseDir } = nodeFsDriverState;\n\n if (!baseDir) {\n return;\n }\n\n await fs.rm(baseDir, { recursive: true, force: true });\n await fs.mkdir(baseDir, { recursive: true });\n },\n /** Reads and parses a stored value; returns null when the file is missing. */\n async getItem<T>(key: string): Promise<T | null> {\n const { baseDir } = nodeFsDriverState;\n const filePath = getFilePath(key, baseDir);\n\n try {\n const content = await fs.readFile(filePath, 'utf8');\n\n return JSON.parse(content) as T;\n }\n catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return null;\n }\n throw error;\n }\n },\n /** Iterates through all keys, invoking the iterator until it returns a value. */\n async iterate<T, U>(iterator: (value: T, key: string, iterationNumber: number) => U): Promise<U> {\n const keys = await nodeFsDriver.keys();\n let iterationNumber = 1;\n\n for (const key of keys) {\n const value = await nodeFsDriver.getItem<T>(key);\n\n const result = iterator(value as T, key, iterationNumber);\n\n if (result !== undefined) {\n return result;\n }\n iterationNumber += 1;\n }\n\n return undefined as unknown as U;\n },\n /** Returns the key name at the given index or null when out of bounds. */\n async key(keyIndex: number): Promise<string> {\n const keys = await nodeFsDriver.keys();\n\n return keys[keyIndex] ?? null as unknown as string;\n },\n /** Lists all stored keys. */\n async keys(): Promise<string[]> {\n const { baseDir } = nodeFsDriverState;\n\n try {\n const files = await fs.readdir(baseDir);\n\n return files\n .filter(file => file.endsWith(STORAGE_KEY_EXTENSION))\n .map(decodeKey);\n }\n catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return [];\n }\n throw error;\n }\n },\n /** Returns the count of stored keys. */\n async length(): Promise<number> {\n const keys = await nodeFsDriver.keys();\n\n return keys.length;\n },\n /** Removes a stored value for the given key. */\n async removeItem(key: string): Promise<void> {\n const { baseDir } = nodeFsDriverState;\n const filePath = getFilePath(key, baseDir);\n\n await fs.rm(filePath, { force: true });\n },\n /** Stores a value as JSON on disk. */\n async setItem<T>(key: string, value: T): Promise<T> {\n const { baseDir } = nodeFsDriverState;\n const filePath = getFilePath(key, baseDir);\n\n await fs.mkdir(baseDir, { recursive: true });\n await fs.writeFile(filePath, JSON.stringify(value), 'utf8');\n\n return value;\n },\n};\n\nlet initPromise: Promise<void> | null = null;\nlet driverInstance: LocalForageDriver | null = null;\n\n/**\n * Prepares and returns the filesystem-backed localForage driver.\n * We bypass localForage's default driver selection and explicitly initialize\n * our custom driver to ensure Node compatibility.\n */\nasync function ensureLocalForageReady(): Promise<LocalForageDriver> {\n if (initPromise) {\n await initPromise;\n return driverInstance as LocalForageDriver;\n }\n\n initPromise = (async () => {\n await localForage.defineDriver(nodeFsDriver);\n nodeFsDriverState.baseDir = getEnv().CYBERSKILL_STORAGE_DIRECTORY;\n const driver = await localForage.getDriver(NODE_FS_DRIVER_NAME);\n\n const initOptions = {\n baseDir: nodeFsDriverState.baseDir,\n name: STORAGE_INSTANCE_NAME,\n storeName: STORAGE_STORE_NAME,\n } satisfies NodeLocalForageOptions;\n\n await driver._initStorage(initOptions as unknown as Parameters<typeof driver._initStorage>[0]);\n driverInstance = driver;\n })().catch((error) => {\n initPromise = null;\n throw error;\n });\n\n await initPromise;\n\n return driverInstance as LocalForageDriver;\n}\n\n/**\n * Persistent storage utility object for data persistence across application sessions.\n * This object provides methods for storing, retrieving, and managing data using localForage,\n * with automatic initialization and error handling.\n */\nexport const storage = {\n /**\n * Retrieves a value from persistent storage by key.\n * This method fetches data that was previously stored using the set method.\n * Returns null if the key doesn't exist or if an error occurs.\n *\n * @param key - The unique identifier for the stored value.\n * @returns A promise that resolves to the stored value or null if not found.\n */\n async get<T = unknown>(key: string): Promise<T | null> {\n try {\n const driver = await ensureLocalForageReady();\n const result = await driver.getItem<T>(key);\n\n return result ?? null;\n }\n catch (error) {\n return catchError(error, { returnValue: null });\n }\n },\n /**\n * Stores a value in persistent storage with a unique key.\n * This method saves data that can be retrieved later using the get method.\n * The data is automatically serialized and stored in the configured storage directory.\n *\n * @param key - The unique identifier for the value to store.\n * @param value - The data to store (will be automatically serialized).\n * @returns A promise that resolves when the storage operation is complete.\n */\n async set<T = unknown>(key: string, value: T): Promise<void> {\n try {\n const driver = await ensureLocalForageReady();\n\n await driver.setItem(key, value);\n }\n catch (error) {\n catchError(error);\n }\n },\n /**\n * Removes a value from persistent storage by key.\n * This method permanently deletes the stored data associated with the specified key.\n *\n * @param key - The unique identifier of the value to remove.\n * @returns A promise that resolves when the removal operation is complete.\n */\n async remove(key: string): Promise<void> {\n try {\n const driver = await ensureLocalForageReady();\n\n await driver.removeItem(key);\n }\n catch (error) {\n catchError(error);\n }\n },\n /**\n * Retrieves all storage keys.\n * This method returns an array of all keys that currently have stored values.\n * Returns an empty array if no keys exist or if an error occurs.\n *\n * @returns A promise that resolves to an array of storage keys.\n */\n async keys(): Promise<string[]> {\n try {\n const driver = await ensureLocalForageReady();\n const keys = await driver.keys();\n\n if (!Array.isArray(keys)) {\n log.warn(`[Storage:keys] Invalid keys response:`, keys);\n return [];\n }\n\n return keys;\n }\n catch (error) {\n return catchError(error, { returnValue: [] });\n }\n },\n /**\n * Gets a human-readable log link for a storage key.\n * This method provides a formatted string that shows the storage directory path\n * and the key name for debugging and manual inspection purposes.\n *\n * @param key - The storage key to generate a log link for.\n * @returns A promise that resolves to a formatted log link string or null if an error occurs.\n */\n async getLogLink(key: string): Promise<string | null> {\n try {\n const storagePath = path.join(getEnv().CYBERSKILL_STORAGE_DIRECTORY, encodeKey(key));\n\n return `${storagePath} (key: ${key})`;\n }\n catch (error) {\n return catchError(error, { returnValue: null });\n }\n },\n\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"storage.util.js","names":[],"sources":["../../../src/node/storage/storage.util.ts"],"sourcesContent":["import localForage from 'localforage';\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\n\nimport { getEnv } from '#config/env/index.js';\n\nimport type { LocalForageDriver, NodeFsDriverState, NodeLocalForageOptions } from './storage.type.js';\n\nimport { catchError, log } from '../log/index.js';\nimport { NODE_FS_DRIVER_NAME, STORAGE_INSTANCE_NAME, STORAGE_KEY_EXTENSION, STORAGE_STORE_NAME } from './storage.constant.js';\n\nconst nodeFsDriverState: NodeFsDriverState = {\n baseDir: '',\n};\n\n/**\n * Encodes a storage key into a filename-safe string.\n */\nfunction encodeKey(key: string): string {\n return `${encodeURIComponent(key)}${STORAGE_KEY_EXTENSION}`;\n}\n\n/**\n * Decodes a filename-safe key back to the original storage key.\n */\nfunction decodeKey(fileName: string): string {\n return decodeURIComponent(fileName.slice(0, -STORAGE_KEY_EXTENSION.length));\n}\n\n/**\n * Maps a storage key to an absolute file path inside the storage directory.\n */\nfunction getFilePath(key: string, baseDir: string): string {\n return path.join(baseDir, encodeKey(key));\n}\n\n/**\n * Custom localForage driver that stores JSON-encoded values on the filesystem.\n */\nconst nodeFsDriver: LocalForageDriver = {\n _driver: NODE_FS_DRIVER_NAME,\n _support: true,\n /** Ensures the storage directory exists and respects custom baseDir overrides. */\n async _initStorage(options: unknown) {\n try {\n const baseDirFromOptions = typeof options === 'object' && options !== null && 'baseDir' in options\n ? (options as { baseDir?: unknown }).baseDir\n : undefined;\n\n if (typeof baseDirFromOptions === 'string' && baseDirFromOptions.length > 0) {\n nodeFsDriverState.baseDir = baseDirFromOptions;\n }\n else {\n nodeFsDriverState.baseDir = getEnv().CYBERSKILL_STORAGE_DIRECTORY;\n }\n\n await fs.mkdir(nodeFsDriverState.baseDir, { recursive: true });\n }\n catch (error) {\n log.error('[Storage:init]', error);\n throw error;\n }\n },\n /** Deletes all stored entries by recreating the directory. Callers must ensure no concurrent operations. */\n async clear() {\n const { baseDir } = nodeFsDriverState;\n\n if (!baseDir) {\n return;\n }\n\n await fs.rm(baseDir, { recursive: true, force: true });\n await fs.mkdir(baseDir, { recursive: true });\n },\n /** Reads and parses a stored value; returns null when the file is missing. */\n async getItem<T>(key: string): Promise<T | null> {\n const { baseDir } = nodeFsDriverState;\n const filePath = getFilePath(key, baseDir);\n\n try {\n const content = await fs.readFile(filePath, 'utf8');\n\n return JSON.parse(content) as T;\n }\n catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return null;\n }\n throw error;\n }\n },\n /** Iterates through all keys, invoking the iterator until it returns a value. */\n async iterate<T, U>(iterator: (value: T, key: string, iterationNumber: number) => U): Promise<U> {\n const keys = await nodeFsDriver.keys();\n let iterationNumber = 1;\n\n for (const key of keys) {\n const value = await nodeFsDriver.getItem<T>(key);\n\n const result = iterator(value as T, key, iterationNumber);\n\n if (result !== undefined) {\n return result;\n }\n iterationNumber += 1;\n }\n\n return undefined as unknown as U;\n },\n /** Returns the key name at the given index or null when out of bounds. */\n async key(keyIndex: number): Promise<string> {\n const keys = await nodeFsDriver.keys();\n\n return keys[keyIndex] ?? null as unknown as string;\n },\n /** Lists all stored keys. */\n async keys(): Promise<string[]> {\n const { baseDir } = nodeFsDriverState;\n\n try {\n const files = await fs.readdir(baseDir);\n\n return files\n .filter(file => file.endsWith(STORAGE_KEY_EXTENSION))\n .map(decodeKey);\n }\n catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n return [];\n }\n throw error;\n }\n },\n /** Returns the count of stored keys. */\n async length(): Promise<number> {\n const keys = await nodeFsDriver.keys();\n\n return keys.length;\n },\n /** Removes a stored value for the given key. */\n async removeItem(key: string): Promise<void> {\n const { baseDir } = nodeFsDriverState;\n const filePath = getFilePath(key, baseDir);\n\n await fs.rm(filePath, { force: true });\n },\n /** Stores a value as JSON on disk. */\n async setItem<T>(key: string, value: T): Promise<T> {\n const { baseDir } = nodeFsDriverState;\n const filePath = getFilePath(key, baseDir);\n\n await fs.mkdir(baseDir, { recursive: true });\n await fs.writeFile(filePath, JSON.stringify(value), 'utf8');\n\n return value;\n },\n};\n\nlet initPromise: Promise<void> | null = null;\nlet driverInstance: LocalForageDriver | null = null;\n\n/**\n * Prepares and returns the filesystem-backed localForage driver.\n * We bypass localForage's default driver selection and explicitly initialize\n * our custom driver to ensure Node compatibility.\n */\nasync function ensureLocalForageReady(): Promise<LocalForageDriver> {\n if (initPromise) {\n await initPromise;\n return driverInstance as LocalForageDriver;\n }\n\n initPromise = (async () => {\n await localForage.defineDriver(nodeFsDriver);\n nodeFsDriverState.baseDir = getEnv().CYBERSKILL_STORAGE_DIRECTORY;\n const driver = await localForage.getDriver(NODE_FS_DRIVER_NAME);\n\n const initOptions = {\n baseDir: nodeFsDriverState.baseDir,\n name: STORAGE_INSTANCE_NAME,\n storeName: STORAGE_STORE_NAME,\n } satisfies NodeLocalForageOptions;\n\n await driver._initStorage(initOptions as unknown as Parameters<typeof driver._initStorage>[0]);\n driverInstance = driver;\n })().catch((error) => {\n initPromise = null;\n throw error;\n });\n\n await initPromise;\n\n return driverInstance as LocalForageDriver;\n}\n\n/**\n * Persistent storage utility object for data persistence across application sessions.\n * This object provides methods for storing, retrieving, and managing data using localForage,\n * with automatic initialization and error handling.\n */\nexport const storage = {\n /**\n * Retrieves a value from persistent storage by key.\n * This method fetches data that was previously stored using the set method.\n * Returns null if the key doesn't exist or if an error occurs.\n *\n * @param key - The unique identifier for the stored value.\n * @returns A promise that resolves to the stored value or null if not found.\n */\n async get<T = unknown>(key: string): Promise<T | null> {\n try {\n const driver = await ensureLocalForageReady();\n const result = await driver.getItem<T>(key);\n\n return result ?? null;\n }\n catch (error) {\n return catchError(error, { returnValue: null });\n }\n },\n /**\n * Stores a value in persistent storage with a unique key.\n * This method saves data that can be retrieved later using the get method.\n * The data is automatically serialized and stored in the configured storage directory.\n *\n * @param key - The unique identifier for the value to store.\n * @param value - The data to store (will be automatically serialized).\n * @returns A promise that resolves when the storage operation is complete.\n */\n async set<T = unknown>(key: string, value: T): Promise<void> {\n try {\n const driver = await ensureLocalForageReady();\n\n await driver.setItem(key, value);\n }\n catch (error) {\n catchError(error);\n }\n },\n /**\n * Removes a value from persistent storage by key.\n * This method permanently deletes the stored data associated with the specified key.\n *\n * @param key - The unique identifier of the value to remove.\n * @returns A promise that resolves when the removal operation is complete.\n */\n async remove(key: string): Promise<void> {\n try {\n const driver = await ensureLocalForageReady();\n\n await driver.removeItem(key);\n }\n catch (error) {\n catchError(error);\n }\n },\n /**\n * Retrieves all storage keys.\n * This method returns an array of all keys that currently have stored values.\n * Returns an empty array if no keys exist or if an error occurs.\n *\n * @returns A promise that resolves to an array of storage keys.\n */\n async keys(): Promise<string[]> {\n try {\n const driver = await ensureLocalForageReady();\n const keys = await driver.keys();\n\n if (!Array.isArray(keys)) {\n log.warn(`[Storage:keys] Invalid keys response:`, keys);\n return [];\n }\n\n return keys;\n }\n catch (error) {\n return catchError(error, { returnValue: [] });\n }\n },\n /**\n * Gets a human-readable log link for a storage key.\n * This method provides a formatted string that shows the storage directory path\n * and the key name for debugging and manual inspection purposes.\n *\n * @param key - The storage key to generate a log link for.\n * @returns A promise that resolves to a formatted log link string or null if an error occurs.\n */\n async getLogLink(key: string): Promise<string | null> {\n try {\n const storagePath = path.join(getEnv().CYBERSKILL_STORAGE_DIRECTORY, encodeKey(key));\n\n return `${storagePath} (key: ${key})`;\n }\n catch (error) {\n return catchError(error, { returnValue: null });\n }\n },\n\n};\n\n/**\n * Resets all module-level singleton state used by the storage module.\n * Intended for use in tests to ensure isolation between test cases.\n * Do NOT call this in production code.\n */\nexport function resetStorageForTesting(): void {\n initPromise = null;\n driverInstance = null;\n nodeFsDriverState.baseDir = '';\n}\n"],"mappings":"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"}
|
|
@@ -8,11 +8,8 @@ import { I_CatchErrorOptions } from './log.type.js';
|
|
|
8
8
|
export declare const log: I_Log;
|
|
9
9
|
/**
|
|
10
10
|
* Catches and handles errors with configurable behavior for React applications.
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* The function handles different error input types and provides consistent error
|
|
15
|
-
* response formatting for React applications.
|
|
11
|
+
* Delegates to the shared `baseCatchError` implementation, using the browser
|
|
12
|
+
* consola instance for logging.
|
|
16
13
|
*
|
|
17
14
|
* @param errorInput - The error to catch and handle, can be Error object, string, or unknown type.
|
|
18
15
|
* @param options - Configuration options for error handling behavior.
|