create-weave-backend-app 0.23.0 → 0.24.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.
@@ -76,11 +76,11 @@ function tryGitInit(root) {
76
76
  //#endregion
77
77
  //#region src/versions.js
78
78
  const versions = {
79
- "@inditextech/weave-types": "0.23.0",
80
- "@inditextech/weave-sdk": "0.23.0",
81
- "@inditextech/weave-store-websockets": "0.23.0",
82
- "@inditextech/weave-store-azure-web-pubsub": "0.23.0",
83
- "@inditextech/weave-react": "0.23.0"
79
+ "@inditextech/weave-types": "0.24.0",
80
+ "@inditextech/weave-sdk": "0.24.0",
81
+ "@inditextech/weave-store-websockets": "0.24.0",
82
+ "@inditextech/weave-store-azure-web-pubsub": "0.24.0",
83
+ "@inditextech/weave-react": "0.24.0"
84
84
  };
85
85
 
86
86
  //#endregion
@@ -341,4 +341,4 @@ function pick(obj, keys) {
341
341
 
342
342
  //#endregion
343
343
  export { create, cwd, getPackageManager };
344
- //# sourceMappingURL=create-app-C_sHOvXR.js.map
344
+ //# sourceMappingURL=create-app-BaW3yEOq.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-app-BaW3yEOq.js","names":["cwd: string","root: string","manager: PackageManager","dest: string","options: Options","file: string","dest: string","projectName: string","from: string","to: string","rename: (s: string) => string","obj: T","keys: K[]","result: Partial<T>"],"sources":["../src/git.ts","../src/versions.js","../template/package.json","../src/auto-install.ts","../src/constants.ts","../src/create-app.ts"],"sourcesContent":["import { execSync } from 'node:child_process';\nimport { rmSync } from 'node:fs';\nimport { join } from 'node:path';\n\n/*\nInitialize a Git repo on the project.\n\nBased on https://github.com/vercel/next.js/blob/canary/packages/create-next-app/helpers/git.ts\n*/\n\nfunction isInGitRepository(cwd: string): boolean {\n try {\n execSync('git rev-parse --is-inside-work-tree', { stdio: 'ignore', cwd });\n return true;\n } catch {\n return false;\n }\n}\n\nfunction isInMercurialRepository(cwd: string): boolean {\n try {\n execSync('hg --cwd . root', { stdio: 'ignore', cwd });\n return true;\n } catch {\n return false;\n }\n}\n\nfunction isDefaultBranchSet(cwd: string): boolean {\n try {\n execSync('git config init.defaultBranch', { stdio: 'ignore', cwd });\n return true;\n } catch {\n return false;\n }\n}\n\nexport function tryGitInit(root: string): boolean {\n let didInit = false;\n\n try {\n execSync('git --version', { stdio: 'ignore' });\n if (isInGitRepository(root) || isInMercurialRepository(root)) {\n return false;\n }\n\n execSync('git init', { stdio: 'ignore', cwd: root });\n didInit = true;\n\n if (!isDefaultBranchSet(root)) {\n execSync('git checkout -b main', { stdio: 'ignore', cwd: root });\n }\n\n execSync('git add -A', { stdio: 'ignore', cwd: root });\n execSync('git commit -m \"Initial commit from Create Fumadocs App\"', {\n stdio: 'ignore',\n cwd: root,\n });\n return true;\n } catch {\n if (didInit) {\n try {\n rmSync(join(root, '.git'), { recursive: true, force: true });\n } catch {\n // do nothing\n }\n }\n\n return false;\n }\n}\n","export const versions = {\"@inditextech/weave-types\":\"0.24.0\",\"@inditextech/weave-sdk\":\"0.24.0\",\"@inditextech/weave-store-websockets\":\"0.24.0\",\"@inditextech/weave-store-azure-web-pubsub\":\"0.24.0\",\"@inditextech/weave-react\":\"0.24.0\"}","{\n \"name\": \"example-versions\",\n \"version\": \"0.0.0\",\n \"private\": true,\n \"description\": \"Used to track dependency versions in create-*-app\",\n \"license\": \"MIT\",\n \"dependencies\": {\n \"@dotenvx/dotenvx\": \"^1.44.0\",\n \"@imgly/background-removal-node\": \"^1.4.5\",\n \"@inditextech/weave-sdk\": \"0.0.0\",\n \"@inditextech/weave-store-websockets\": \"0.0.0\",\n \"@inditextech/weave-store-azure-web-pubsub\": \"0.0.0\",\n \"cors\": \"^2.8.5\",\n \"dotenv\": \"^16.4.7\",\n \"express\": \"^4.21.2\",\n \"helmet\": \"^8.0.0\",\n \"morgan\": \"^1.10.0\",\n \"multer\": \"^1.4.5-lts.1\",\n \"pino\": \"^9.6.0\",\n \"pino-http\": \"^10.4.0\",\n \"pino-pretty\": \"^13.0.0\",\n \"tslib\": \"^2.8.1\",\n \"tsx\": \"^4.19.3\",\n \"uuid\": \"^11.1.0\",\n \"zod\": \"^3.24.2\"\n },\n \"devDependencies\": {\n \"@eslint/js\": \"^9.26.0\",\n \"@types/cors\": \"^2.8.17\",\n \"@types/express\": \"^5.0.0\",\n \"@types/morgan\": \"^1.9.9\",\n \"@types/multer\": \"^1.4.12\",\n \"@types/node\": \"^22.13.5\",\n \"@typescript-eslint/eslint-plugin\": \"^8.25.0\",\n \"@typescript-eslint/parser\": \"^8.25.0\",\n \"cp-cli\": \"^2.0.0\",\n \"eslint\": \"^9.26.0\",\n \"eslint-config-prettier\": \"^10.1.5\",\n \"globals\": \"^16.0.0\",\n \"nodemon\": \"^3.1.9\",\n \"prettier\": \"^3.5.2\",\n \"tsc-alias\": \"^1.8.16\",\n \"tsconfig-paths\": \"^4.2.0\",\n \"typescript\": \"^5.7.3\",\n \"typescript-eslint\": \"^8.25.0\"\n }\n}\n","import { spawn } from 'cross-spawn';\n\nexport type PackageManager = 'npm' | 'pnpm' | 'yarn' | 'bun';\n\nexport function getPackageManager(): PackageManager {\n const userAgent = process.env.npm_config_user_agent ?? '';\n\n if (userAgent.startsWith('yarn')) {\n return 'yarn';\n }\n\n if (userAgent.startsWith('pnpm')) {\n return 'pnpm';\n }\n\n if (userAgent.startsWith('bun')) {\n return 'bun';\n }\n\n return 'npm';\n}\n\nexport function autoInstall(\n manager: PackageManager,\n dest: string\n): Promise<void> {\n return new Promise((res, reject) => {\n const installProcess = spawn(manager, ['install'], {\n stdio: 'ignore',\n env: {\n ...process.env,\n NODE_ENV: 'development',\n DISABLE_OPENCOLLECTIVE: '1',\n },\n cwd: dest,\n });\n\n installProcess.on('close', (code) => {\n if (code !== 0) {\n reject(new Error('Install failed'));\n } else {\n res();\n }\n });\n });\n}\n","import { fileURLToPath } from 'node:url';\n\nexport const sourceDir = fileURLToPath(new URL(`../`, import.meta.url).href);\nexport const cwd = process.cwd();\n","import path from 'node:path';\nimport fs from 'node:fs/promises';\nimport { tryGitInit } from '@/git';\nimport { versions as localVersions } from '@/versions';\nimport versionPkg from './../template/package.json';\nimport type { PackageManager } from './auto-install';\nimport { autoInstall } from './auto-install';\nimport { cwd, sourceDir } from './constants';\n\nexport type Template = '+express+websockets' | '+express+azure-web-pubsub';\n\nexport interface Options {\n outputDir: string;\n template: Template;\n packageManager: PackageManager;\n installDeps?: boolean;\n initializeGit?: boolean;\n log?: (message: string) => void;\n}\n\nexport async function create(options: Options): Promise<void> {\n const {\n installDeps = true,\n initializeGit = true,\n log = console.log,\n } = options;\n const projectName = path.basename(options.outputDir);\n const dest = path.resolve(cwd, options.outputDir);\n\n function defaultRename(file: string): string {\n file = file.replace('example.gitignore', '.gitignore');\n file = file.replace('example.env', '.env');\n\n return file;\n }\n\n await copy(\n path.join(sourceDir, `template/${options.template}`),\n dest,\n defaultRename\n );\n\n // update tsconfig.json for src dir\n // if (isNext && options.useSrcDir) {\n const tsconfigPath = path.join(dest, 'tsconfig.json');\n const content = (await fs.readFile(tsconfigPath)).toString();\n\n const config = JSON.parse(content);\n\n if (config.compilerOptions?.paths) {\n Object.assign(config.compilerOptions.paths, {\n '@/*': ['./src/*'],\n });\n }\n\n await fs.writeFile(tsconfigPath, JSON.stringify(config, null, 2));\n // }\n\n const packageJson = createPackageJson(projectName, options);\n await fs.writeFile(\n path.join(dest, 'package.json'),\n JSON.stringify(packageJson, null, 2)\n );\n\n const readMe = await getReadme(dest, projectName);\n await fs.writeFile(path.join(dest, 'README.md'), readMe);\n\n if (installDeps) {\n await autoInstall(options.packageManager, dest);\n log('Installed dependencies');\n }\n\n if (initializeGit && tryGitInit(dest)) {\n log('Initialized Git repository');\n }\n}\n\nasync function getReadme(dest: string, projectName: string): Promise<string> {\n const template = await fs\n .readFile(path.join(dest, 'README.md'))\n .then((res) => res.toString());\n\n return `# ${projectName}\\n\\n${template}`;\n}\n\nasync function copy(\n from: string,\n to: string,\n rename: (s: string) => string = (s) => s\n): Promise<void> {\n const stats = await fs.stat(from);\n\n if (stats.isDirectory()) {\n const files = await fs.readdir(from);\n\n await Promise.all(\n files.map((file) =>\n copy(path.join(from, file), rename(path.join(to, file)))\n )\n );\n } else {\n await fs.mkdir(path.dirname(to), { recursive: true });\n await fs.copyFile(from, to);\n }\n}\n\nfunction createPackageJson(projectName: string, options: Options): object {\n if (options.template === '+express+azure-web-pubsub') {\n const dependencies = {\n ...pick(localVersions, [\n '@inditextech/weave-sdk',\n '@inditextech/weave-store-azure-web-pubsub',\n ]),\n ...pick(versionPkg.dependencies, [\n '@dotenvx/dotenvx',\n '@imgly/background-removal-node',\n 'cors',\n 'dotenv',\n 'express',\n 'helmet',\n 'morgan',\n 'multer',\n 'pino',\n 'pino-http',\n 'pino-pretty',\n 'tslib',\n 'tsx',\n 'uuid',\n 'zod',\n ]),\n };\n\n const devDependencies = {\n ...pick(versionPkg.devDependencies, [\n '@eslint/js',\n '@types/cors',\n '@types/express',\n '@types/morgan',\n '@types/multer',\n '@types/node',\n '@typescript-eslint/eslint-plugin',\n '@typescript-eslint/parser',\n 'cp-cli',\n 'eslint',\n 'eslint-config-prettier',\n 'globals',\n 'nodemon',\n 'prettier',\n 'tsc-alias',\n 'tsconfig-paths',\n 'typescript',\n 'typescript-eslint',\n ]),\n };\n\n return {\n name: projectName,\n type: 'module',\n scripts: {\n build:\n 'tsc && tsc-alias -p tsconfig.json && mkdir -p ./dist/public && mkdir -p ./dist/temp && cp-cli ./public ./dist/public && cp-cli ./package.json ./dist/package.json',\n copyAssets:\n 'mkdir -p ./public && cp-cli node_modules/@imgly/background-removal-node/dist/. public',\n dev: 'nodemon --exec \"dotenvx run -- tsx src/server.ts\"',\n format: 'prettier --write \"src/**/*.{ts,tsx}\"',\n lint: 'eslint ./src',\n postinstall: 'npm run copyAssets',\n start: 'dotenvx run -- tsx server.js',\n },\n private: true,\n dependencies: sortObjectKeys(dependencies),\n devDependencies: sortObjectKeys(devDependencies),\n };\n }\n\n const dependencies = {\n ...pick(versionPkg.dependencies, [\n '@dotenvx/dotenvx',\n '@imgly/background-removal-node',\n 'cors',\n 'dotenv',\n 'express',\n 'helmet',\n 'morgan',\n 'multer',\n 'pino',\n 'pino-http',\n 'pino-pretty',\n 'tslib',\n 'tsx',\n 'uuid',\n 'zod',\n ]),\n ...pick(localVersions, [\n '@inditextech/weave-sdk',\n '@inditextech/weave-store-websockets',\n ]),\n };\n\n const devDependencies = {\n ...pick(versionPkg.devDependencies, [\n '@eslint/js',\n '@types/cors',\n '@types/express',\n '@types/morgan',\n '@types/multer',\n '@types/node',\n '@typescript-eslint/eslint-plugin',\n '@typescript-eslint/parser',\n 'cp-cli',\n 'eslint',\n 'eslint-config-prettier',\n 'globals',\n 'nodemon',\n 'prettier',\n 'tsc-alias',\n 'tsconfig-paths',\n 'typescript',\n 'typescript-eslint',\n ]),\n };\n\n return {\n name: projectName,\n version: '0.0.0',\n private: true,\n scripts: {\n build:\n 'tsc && tsc-alias -p tsconfig.json && mkdir -p ./dist/public && mkdir -p ./dist/temp && cp-cli ./public ./dist/public && cp-cli ./package.json ./dist/package.json',\n copyAssets:\n 'mkdir -p ./public && cp-cli node_modules/@imgly/background-removal-node/dist/. public',\n dev: 'nodemon --exec \"dotenvx run -- tsx src/server.ts\"',\n format: 'prettier --write \"src/**/*.{ts,tsx}\"',\n lint: 'eslint ./src',\n postinstall: 'npm run copyAssets',\n start: 'dotenvx run -- tsx server.js',\n },\n dependencies: sortObjectKeys(dependencies),\n devDependencies: sortObjectKeys(devDependencies),\n };\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction sortObjectKeys<T extends Record<string, any>>(obj: T): T {\n const sortedEntries = Object.keys(obj)\n .sort()\n .map((key) => [key, obj[key]] as [keyof T, T[keyof T]]);\n\n return Object.fromEntries(sortedEntries) as T;\n}\n\nfunction pick<T extends object, K extends keyof T>(\n obj: T,\n keys: K[]\n): Pick<T, K> {\n const result: Partial<T> = {};\n\n for (const key of keys) {\n if (key in obj) {\n result[key] = obj[key];\n }\n }\n\n return result as Pick<T, K>;\n}\n"],"mappings":"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CA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;GACD,EAAC;EACH;EAED,MAAM,oBAAkB,EACtB,GAAG,KAAK,gBAAW,iBAAiB;GAClC;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACD,EAAC,CACH;AAED,SAAO;GACL,MAAM;GACN,MAAM;GACN,SAAS;IACP,OACE;IACF,YACE;IACF,KAAK;IACL,QAAQ;IACR,MAAM;IACN,aAAa;IACb,OAAO;GACR;GACD,SAAS;GACT,cAAc,eAAe,eAAa;GAC1C,iBAAiB,eAAe,kBAAgB;EACjD;CACF;CAED,MAAM,iBAAe;EACnB,GAAG,KAAK,gBAAW,cAAc;GAC/B;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACD,EAAC;EACF,GAAG,KAAK,UAAe,CACrB,0BACA,qCACD,EAAC;CACH;CAED,MAAM,oBAAkB,EACtB,GAAG,KAAK,gBAAW,iBAAiB;EAClC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACD,EAAC,CACH;AAED,QAAO;EACL,MAAM;EACN,SAAS;EACT,SAAS;EACT,SAAS;GACP,OACE;GACF,YACE;GACF,KAAK;GACL,QAAQ;GACR,MAAM;GACN,aAAa;GACb,OAAO;EACR;EACD,cAAc,eAAe,eAAa;EAC1C,iBAAiB,eAAe,kBAAgB;CACjD;AACF;AAGD,SAAS,eAA8CO,KAAW;CAChE,MAAM,gBAAgB,OAAO,KAAK,IAAI,CACnC,MAAM,CACN,IAAI,CAAC,QAAQ,CAAC,KAAK,IAAI,IAAK,EAA0B;AAEzD,QAAO,OAAO,YAAY,cAAc;AACzC;AAED,SAAS,KACPA,KACAC,MACY;CACZ,MAAMC,SAAqB,CAAE;AAE7B,MAAK,MAAM,OAAO,KAChB,KAAI,OAAO,IACT,QAAO,OAAO,IAAI;AAItB,QAAO;AACR"}
@@ -1,3 +1,3 @@
1
- import { create } from "./create-app-C_sHOvXR.js";
1
+ import { create } from "./create-app-BaW3yEOq.js";
2
2
 
3
3
  export { create };
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { create, cwd, getPackageManager } from "./create-app-C_sHOvXR.js";
2
+ import { create, cwd, getPackageManager } from "./create-app-BaW3yEOq.js";
3
3
  import path from "node:path";
4
4
  import fs from "node:fs/promises";
5
5
  import { cancel, confirm, group, intro, isCancel, outro, select, spinner, text } from "@clack/prompts";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-weave-backend-app",
3
- "version": "0.23.0",
3
+ "version": "0.24.0",
4
4
  "description": "Create a new backend artifact for site with Weave.js",
5
5
  "keywords": [
6
6
  "NextJs",
@@ -25,6 +25,7 @@
25
25
  "build": "tsc --noEmit && tsdown",
26
26
  "clean": "rimraf dist",
27
27
  "dev": "tsdown --watch",
28
+ "format": "prettier --write ./src ./template",
28
29
  "link": "npm link",
29
30
  "lint:fix": "npm run lint -- --fix",
30
31
  "lint": "eslint ./src",
@@ -1,21 +1,21 @@
1
- import js from '@eslint/js';
2
- import globals from 'globals';
3
- import tseslint from 'typescript-eslint';
4
- import { defineConfig } from 'eslint/config';
5
- import eslintConfigPrettier from 'eslint-config-prettier';
1
+ import js from '@eslint/js'
2
+ import globals from 'globals'
3
+ import tseslint from 'typescript-eslint'
4
+ import { defineConfig } from 'eslint/config'
5
+ import eslintConfigPrettier from 'eslint-config-prettier'
6
6
 
7
7
  export default defineConfig([
8
8
  {
9
9
  files: ['**/*.{js,mjs,cjs,ts}'],
10
10
  ignores: ['dist/**/*'],
11
11
  plugins: { js },
12
- extends: ['js/recommended'],
12
+ extends: ['js/recommended']
13
13
  },
14
14
  {
15
15
  files: ['**/*.{js,mjs,cjs,ts}'],
16
16
  ignores: ['dist/**/*'],
17
- languageOptions: { globals: globals.browser },
17
+ languageOptions: { globals: globals.browser }
18
18
  },
19
19
  tseslint.configs.recommended,
20
- eslintConfigPrettier,
21
- ]);
20
+ eslintConfigPrettier
21
+ ])
@@ -1,145 +1,142 @@
1
- import { promises as fs } from 'fs';
2
- import path from 'path';
3
- import { Logger } from 'pino';
4
- import { getLogger } from '../logger/logger.js';
5
- import { createFolder, existsFolder, getFileContents } from '@/utils.js';
1
+ import { promises as fs } from 'fs'
2
+ import path from 'path'
3
+ import { Logger } from 'pino'
4
+ import { getLogger } from '../logger/logger.js'
5
+ import { createFolder, existsFolder, getFileContents } from '@/utils.js'
6
6
 
7
- const IMAGES_FOLDER = './images';
8
- const IMAGES_MIME_TYPE_FOLDER = './images-mimetype';
7
+ const IMAGES_FOLDER = './images'
8
+ const IMAGES_MIME_TYPE_FOLDER = './images-mimetype'
9
9
 
10
10
  export class ImagesPersistenceHandler {
11
- private _initialized!: boolean;
12
- private _logger!: Logger;
11
+ private _initialized!: boolean
12
+ private _logger!: Logger
13
13
 
14
14
  constructor() {
15
- this._initialized = false;
16
- this._logger = getLogger().child({ module: 'images.persistence' });
15
+ this._initialized = false
16
+ this._logger = getLogger().child({ module: 'images.persistence' })
17
17
  }
18
18
 
19
19
  isInitialized() {
20
- return this._initialized;
20
+ return this._initialized
21
21
  }
22
22
 
23
23
  async setup() {
24
- const folderPath = path.join(process.cwd(), IMAGES_FOLDER);
24
+ const folderPath = path.join(process.cwd(), IMAGES_FOLDER)
25
25
 
26
26
  if (!(await existsFolder(folderPath))) {
27
- await createFolder(folderPath);
27
+ await createFolder(folderPath)
28
28
  }
29
29
 
30
- const folderMimeTypePath = path.join(
31
- process.cwd(),
32
- IMAGES_MIME_TYPE_FOLDER
33
- );
30
+ const folderMimeTypePath = path.join(process.cwd(), IMAGES_MIME_TYPE_FOLDER)
34
31
 
35
32
  if (!(await existsFolder(folderMimeTypePath))) {
36
- await createFolder(folderMimeTypePath);
33
+ await createFolder(folderMimeTypePath)
37
34
  }
38
35
 
39
- this._initialized = true;
36
+ this._initialized = true
40
37
  }
41
38
 
42
39
  async list(prefix: string, pageSize: number = 20, page: number = 1) {
43
40
  try {
44
41
  if (!this._initialized) {
45
- await this.setup();
42
+ await this.setup()
46
43
  }
47
44
 
48
- const folder = path.join(process.cwd(), IMAGES_FOLDER, prefix);
45
+ const folder = path.join(process.cwd(), IMAGES_FOLDER, prefix)
49
46
 
50
47
  if (!(await existsFolder(folder))) {
51
- await createFolder(folder);
48
+ await createFolder(folder)
52
49
  }
53
50
 
54
- const files = await fs.readdir(folder);
55
- const totalFiles = files.length;
56
- const totalPages = Math.ceil(totalFiles / pageSize);
57
- const start = (page - 1) * pageSize;
58
- const end = start + pageSize;
51
+ const files = await fs.readdir(folder)
52
+ const totalFiles = files.length
53
+ const totalPages = Math.ceil(totalFiles / pageSize)
54
+ const start = (page - 1) * pageSize
55
+ const end = start + pageSize
59
56
 
60
- const paginatedFiles = files.slice(start, end);
57
+ const paginatedFiles = files.slice(start, end)
61
58
 
62
- return { images: paginatedFiles, totalPages, nextPage: page + 1 };
59
+ return { images: paginatedFiles, totalPages, nextPage: page + 1 }
63
60
  } catch (ex) {
64
- this._logger.error({ error: ex }, 'Error getting images list');
65
- return { images: [], continuationToken: undefined };
61
+ this._logger.error({ error: ex }, 'Error getting images list')
62
+ return { images: [], continuationToken: undefined }
66
63
  }
67
64
  }
68
65
 
69
66
  async exists(imageName: string) {
70
67
  try {
71
68
  if (!this._initialized) {
72
- await this.setup();
69
+ await this.setup()
73
70
  }
74
71
 
75
72
  try {
76
- const filePath = path.join(process.cwd(), IMAGES_FOLDER, imageName);
73
+ const filePath = path.join(process.cwd(), IMAGES_FOLDER, imageName)
77
74
 
78
- await fs.access(filePath);
75
+ await fs.access(filePath)
79
76
 
80
- return true;
77
+ return true
81
78
  } catch (err) {
82
79
  this._logger.error(
83
80
  { imageName, error: err },
84
81
  'File does not exist or is not accessible'
85
- );
86
- return false;
82
+ )
83
+ return false
87
84
  }
88
85
  } catch (ex) {
89
86
  this._logger.error(
90
87
  { imageName, error: ex },
91
88
  'Error checking if image exists'
92
- );
93
- return false;
89
+ )
90
+ return false
94
91
  }
95
92
  }
96
93
 
97
94
  async createRoomFolder(imageName: string) {
98
- const imageTokens = imageName.split('/');
99
- const roomFolder = imageTokens[0];
100
- const roomFolderPath = path.join(process.cwd(), IMAGES_FOLDER, roomFolder);
95
+ const imageTokens = imageName.split('/')
96
+ const roomFolder = imageTokens[0]
97
+ const roomFolderPath = path.join(process.cwd(), IMAGES_FOLDER, roomFolder)
101
98
 
102
99
  if (!(await existsFolder(roomFolderPath))) {
103
- await createFolder(roomFolderPath);
100
+ await createFolder(roomFolderPath)
104
101
  }
105
102
  }
106
103
 
107
104
  async createRoomMimeTypeFolder(imageName: string) {
108
- const imageTokens = imageName.split('/');
109
- const roomFolder = imageTokens[0];
105
+ const imageTokens = imageName.split('/')
106
+ const roomFolder = imageTokens[0]
110
107
  const roomMimeTypeFolderPath = path.join(
111
108
  process.cwd(),
112
109
  IMAGES_MIME_TYPE_FOLDER,
113
110
  roomFolder
114
- );
111
+ )
115
112
 
116
113
  if (!(await existsFolder(roomMimeTypeFolderPath))) {
117
- await createFolder(roomMimeTypeFolderPath);
114
+ await createFolder(roomMimeTypeFolderPath)
118
115
  }
119
116
  }
120
117
 
121
118
  async getMimeType(imageName: string) {
122
119
  try {
123
120
  if (!this._initialized) {
124
- await this.setup();
121
+ await this.setup()
125
122
  }
126
123
 
127
- await this.createRoomMimeTypeFolder(imageName);
124
+ await this.createRoomMimeTypeFolder(imageName)
128
125
 
129
126
  const filePath = path.join(
130
127
  process.cwd(),
131
128
  IMAGES_MIME_TYPE_FOLDER,
132
129
  imageName
133
- );
134
- const filePathMimeType = `${filePath}.mimeType`;
130
+ )
131
+ const filePathMimeType = `${filePath}.mimeType`
135
132
 
136
- return await getFileContents(filePathMimeType);
133
+ return await getFileContents(filePathMimeType)
137
134
  } catch (ex) {
138
135
  this._logger.error(
139
136
  { imageName, error: ex },
140
137
  'Error getting image MIME type'
141
- );
142
- return 'application/octet-stream';
138
+ )
139
+ return 'application/octet-stream'
143
140
  }
144
141
  }
145
142
 
@@ -150,90 +147,87 @@ export class ImagesPersistenceHandler {
150
147
  ): Promise<boolean> {
151
148
  try {
152
149
  if (!this._initialized) {
153
- await this.setup();
150
+ await this.setup()
154
151
  }
155
152
 
156
- this._logger.debug({ imageName }, 'Persisting image');
153
+ this._logger.debug({ imageName }, 'Persisting image')
157
154
 
158
- await this.createRoomFolder(imageName);
159
- await this.createRoomMimeTypeFolder(imageName);
155
+ await this.createRoomFolder(imageName)
156
+ await this.createRoomMimeTypeFolder(imageName)
160
157
 
161
- const filePath = path.join(process.cwd(), IMAGES_FOLDER, imageName);
158
+ const filePath = path.join(process.cwd(), IMAGES_FOLDER, imageName)
162
159
  const fileMimeTypePath = path.join(
163
160
  process.cwd(),
164
161
  IMAGES_MIME_TYPE_FOLDER,
165
162
  imageName
166
- );
167
- const filePathMimeType = `${fileMimeTypePath}.mimeType`;
163
+ )
164
+ const filePathMimeType = `${fileMimeTypePath}.mimeType`
168
165
 
169
166
  try {
170
- await fs.writeFile(filePathMimeType, mimeType, { encoding: 'utf-8' });
171
- await fs.writeFile(filePath, content);
167
+ await fs.writeFile(filePathMimeType, mimeType, { encoding: 'utf-8' })
168
+ await fs.writeFile(filePath, content)
172
169
 
173
- this._logger.debug({ imageName }, 'Persisted image');
170
+ this._logger.debug({ imageName }, 'Persisted image')
174
171
 
175
- return true;
172
+ return true
176
173
  } catch (err) {
177
- this._logger.error({ imageName, error: err }, 'Error saving the image');
178
- return false;
174
+ this._logger.error({ imageName, error: err }, 'Error saving the image')
175
+ return false
179
176
  }
180
177
  } catch (ex) {
181
- this._logger.error({ imageName, error: ex }, 'Error persisting image');
182
- return false;
178
+ this._logger.error({ imageName, error: ex }, 'Error persisting image')
179
+ return false
183
180
  }
184
181
  }
185
182
 
186
183
  async delete(imageName: string): Promise<boolean> {
187
184
  try {
188
185
  if (!this._initialized) {
189
- await this.setup();
186
+ await this.setup()
190
187
  }
191
188
 
192
189
  try {
193
- this._logger.debug({ imageName }, 'Deleting image');
190
+ this._logger.debug({ imageName }, 'Deleting image')
194
191
 
195
- await this.createRoomFolder(imageName);
196
- await this.createRoomMimeTypeFolder(imageName);
192
+ await this.createRoomFolder(imageName)
193
+ await this.createRoomMimeTypeFolder(imageName)
197
194
 
198
- const filePath = path.join(process.cwd(), IMAGES_FOLDER, imageName);
195
+ const filePath = path.join(process.cwd(), IMAGES_FOLDER, imageName)
199
196
  const fileMimeTypePath = path.join(
200
197
  process.cwd(),
201
198
  IMAGES_MIME_TYPE_FOLDER,
202
199
  imageName
203
- );
204
- const filePathMimeType = `${fileMimeTypePath}.mimeType`;
200
+ )
201
+ const filePathMimeType = `${fileMimeTypePath}.mimeType`
205
202
 
206
203
  if (!(await this.exists(imageName))) {
207
- this._logger.debug({ imageName }, 'Image not found');
208
- return false;
204
+ this._logger.debug({ imageName }, 'Image not found')
205
+ return false
209
206
  }
210
207
 
211
- await fs.unlink(filePath);
212
- await fs.unlink(filePathMimeType);
208
+ await fs.unlink(filePath)
209
+ await fs.unlink(filePathMimeType)
213
210
 
214
- this._logger.debug({ imageName }, 'Deleted image');
211
+ this._logger.debug({ imageName }, 'Deleted image')
215
212
 
216
- return true;
213
+ return true
217
214
  } catch (err) {
218
- this._logger.error(
219
- { imageName, error: err },
220
- 'Error deleting the file'
221
- );
222
- return false;
215
+ this._logger.error({ imageName, error: err }, 'Error deleting the file')
216
+ return false
223
217
  }
224
218
  } catch (ex) {
225
- this._logger.error({ imageName, error: ex }, 'Error deleting the image');
226
- return false;
219
+ this._logger.error({ imageName, error: ex }, 'Error deleting the image')
220
+ return false
227
221
  }
228
222
  }
229
223
 
230
224
  async getFilePath(imageName: string): Promise<string> {
231
225
  if (!this._initialized) {
232
- await this.setup();
226
+ await this.setup()
233
227
  }
234
228
 
235
- const filePath = path.join(process.cwd(), IMAGES_FOLDER, imageName);
229
+ const filePath = path.join(process.cwd(), IMAGES_FOLDER, imageName)
236
230
 
237
- return filePath;
231
+ return filePath
238
232
  }
239
233
  }
@@ -9,7 +9,9 @@ export const getFileContents = async (
9
9
  return content
10
10
  } catch (err) {
11
11
  console.error(
12
- `Error reading file ${filePath}: ${err instanceof Error ? err.message : err}`
12
+ `Error reading file ${filePath}: ${
13
+ err instanceof Error ? err.message : err
14
+ }`
13
15
  )
14
16
  throw err
15
17
  }
@@ -1,21 +1,21 @@
1
- import js from '@eslint/js';
2
- import globals from 'globals';
3
- import tseslint from 'typescript-eslint';
4
- import { defineConfig } from 'eslint/config';
5
- import eslintConfigPrettier from 'eslint-config-prettier';
1
+ import js from '@eslint/js'
2
+ import globals from 'globals'
3
+ import tseslint from 'typescript-eslint'
4
+ import { defineConfig } from 'eslint/config'
5
+ import eslintConfigPrettier from 'eslint-config-prettier'
6
6
 
7
7
  export default defineConfig([
8
8
  {
9
9
  files: ['**/*.{js,mjs,cjs,ts}'],
10
10
  ignores: ['dist/**/*'],
11
11
  plugins: { js },
12
- extends: ['js/recommended'],
12
+ extends: ['js/recommended']
13
13
  },
14
14
  {
15
15
  files: ['**/*.{js,mjs,cjs,ts}'],
16
16
  ignores: ['dist/**/*'],
17
- languageOptions: { globals: globals.browser },
17
+ languageOptions: { globals: globals.browser }
18
18
  },
19
19
  tseslint.configs.recommended,
20
- eslintConfigPrettier,
21
- ]);
20
+ eslintConfigPrettier
21
+ ])
@@ -1,145 +1,142 @@
1
- import { promises as fs } from 'fs';
2
- import path from 'path';
3
- import { Logger } from 'pino';
4
- import { getLogger } from '../logger/logger.js';
5
- import { createFolder, existsFolder, getFileContents } from '@/utils.js';
1
+ import { promises as fs } from 'fs'
2
+ import path from 'path'
3
+ import { Logger } from 'pino'
4
+ import { getLogger } from '../logger/logger.js'
5
+ import { createFolder, existsFolder, getFileContents } from '@/utils.js'
6
6
 
7
- const IMAGES_FOLDER = './images';
8
- const IMAGES_MIME_TYPE_FOLDER = './images-mimetype';
7
+ const IMAGES_FOLDER = './images'
8
+ const IMAGES_MIME_TYPE_FOLDER = './images-mimetype'
9
9
 
10
10
  export class ImagesPersistenceHandler {
11
- private _initialized!: boolean;
12
- private _logger!: Logger;
11
+ private _initialized!: boolean
12
+ private _logger!: Logger
13
13
 
14
14
  constructor() {
15
- this._initialized = false;
16
- this._logger = getLogger().child({ module: 'images.persistence' });
15
+ this._initialized = false
16
+ this._logger = getLogger().child({ module: 'images.persistence' })
17
17
  }
18
18
 
19
19
  isInitialized() {
20
- return this._initialized;
20
+ return this._initialized
21
21
  }
22
22
 
23
23
  async setup() {
24
- const folderPath = path.join(process.cwd(), IMAGES_FOLDER);
24
+ const folderPath = path.join(process.cwd(), IMAGES_FOLDER)
25
25
 
26
26
  if (!(await existsFolder(folderPath))) {
27
- await createFolder(folderPath);
27
+ await createFolder(folderPath)
28
28
  }
29
29
 
30
- const folderMimeTypePath = path.join(
31
- process.cwd(),
32
- IMAGES_MIME_TYPE_FOLDER
33
- );
30
+ const folderMimeTypePath = path.join(process.cwd(), IMAGES_MIME_TYPE_FOLDER)
34
31
 
35
32
  if (!(await existsFolder(folderMimeTypePath))) {
36
- await createFolder(folderMimeTypePath);
33
+ await createFolder(folderMimeTypePath)
37
34
  }
38
35
 
39
- this._initialized = true;
36
+ this._initialized = true
40
37
  }
41
38
 
42
39
  async list(prefix: string, pageSize: number = 20, page: number = 1) {
43
40
  try {
44
41
  if (!this._initialized) {
45
- await this.setup();
42
+ await this.setup()
46
43
  }
47
44
 
48
- const folder = path.join(process.cwd(), IMAGES_FOLDER, prefix);
45
+ const folder = path.join(process.cwd(), IMAGES_FOLDER, prefix)
49
46
 
50
47
  if (!(await existsFolder(folder))) {
51
- await createFolder(folder);
48
+ await createFolder(folder)
52
49
  }
53
50
 
54
- const files = await fs.readdir(folder);
55
- const totalFiles = files.length;
56
- const totalPages = Math.ceil(totalFiles / pageSize);
57
- const start = (page - 1) * pageSize;
58
- const end = start + pageSize;
51
+ const files = await fs.readdir(folder)
52
+ const totalFiles = files.length
53
+ const totalPages = Math.ceil(totalFiles / pageSize)
54
+ const start = (page - 1) * pageSize
55
+ const end = start + pageSize
59
56
 
60
- const paginatedFiles = files.slice(start, end);
57
+ const paginatedFiles = files.slice(start, end)
61
58
 
62
- return { images: paginatedFiles, totalPages, nextPage: page + 1 };
59
+ return { images: paginatedFiles, totalPages, nextPage: page + 1 }
63
60
  } catch (ex) {
64
- this._logger.error({ error: ex }, 'Error getting images list');
65
- return { images: [], continuationToken: undefined };
61
+ this._logger.error({ error: ex }, 'Error getting images list')
62
+ return { images: [], continuationToken: undefined }
66
63
  }
67
64
  }
68
65
 
69
66
  async exists(imageName: string) {
70
67
  try {
71
68
  if (!this._initialized) {
72
- await this.setup();
69
+ await this.setup()
73
70
  }
74
71
 
75
72
  try {
76
- const filePath = path.join(process.cwd(), IMAGES_FOLDER, imageName);
73
+ const filePath = path.join(process.cwd(), IMAGES_FOLDER, imageName)
77
74
 
78
- await fs.access(filePath);
75
+ await fs.access(filePath)
79
76
 
80
- return true;
77
+ return true
81
78
  } catch (err) {
82
79
  this._logger.error(
83
80
  { imageName, error: err },
84
81
  'File does not exist or is not accessible'
85
- );
86
- return false;
82
+ )
83
+ return false
87
84
  }
88
85
  } catch (ex) {
89
86
  this._logger.error(
90
87
  { imageName, error: ex },
91
88
  'Error checking if image exists'
92
- );
93
- return false;
89
+ )
90
+ return false
94
91
  }
95
92
  }
96
93
 
97
94
  async createRoomFolder(imageName: string) {
98
- const imageTokens = imageName.split('/');
99
- const roomFolder = imageTokens[0];
100
- const roomFolderPath = path.join(process.cwd(), IMAGES_FOLDER, roomFolder);
95
+ const imageTokens = imageName.split('/')
96
+ const roomFolder = imageTokens[0]
97
+ const roomFolderPath = path.join(process.cwd(), IMAGES_FOLDER, roomFolder)
101
98
 
102
99
  if (!(await existsFolder(roomFolderPath))) {
103
- await createFolder(roomFolderPath);
100
+ await createFolder(roomFolderPath)
104
101
  }
105
102
  }
106
103
 
107
104
  async createRoomMimeTypeFolder(imageName: string) {
108
- const imageTokens = imageName.split('/');
109
- const roomFolder = imageTokens[0];
105
+ const imageTokens = imageName.split('/')
106
+ const roomFolder = imageTokens[0]
110
107
  const roomMimeTypeFolderPath = path.join(
111
108
  process.cwd(),
112
109
  IMAGES_MIME_TYPE_FOLDER,
113
110
  roomFolder
114
- );
111
+ )
115
112
 
116
113
  if (!(await existsFolder(roomMimeTypeFolderPath))) {
117
- await createFolder(roomMimeTypeFolderPath);
114
+ await createFolder(roomMimeTypeFolderPath)
118
115
  }
119
116
  }
120
117
 
121
118
  async getMimeType(imageName: string) {
122
119
  try {
123
120
  if (!this._initialized) {
124
- await this.setup();
121
+ await this.setup()
125
122
  }
126
123
 
127
- await this.createRoomMimeTypeFolder(imageName);
124
+ await this.createRoomMimeTypeFolder(imageName)
128
125
 
129
126
  const filePath = path.join(
130
127
  process.cwd(),
131
128
  IMAGES_MIME_TYPE_FOLDER,
132
129
  imageName
133
- );
134
- const filePathMimeType = `${filePath}.mimeType`;
130
+ )
131
+ const filePathMimeType = `${filePath}.mimeType`
135
132
 
136
- return await getFileContents(filePathMimeType);
133
+ return await getFileContents(filePathMimeType)
137
134
  } catch (ex) {
138
135
  this._logger.error(
139
136
  { imageName, error: ex },
140
137
  'Error getting image MIME type'
141
- );
142
- return 'application/octet-stream';
138
+ )
139
+ return 'application/octet-stream'
143
140
  }
144
141
  }
145
142
 
@@ -150,90 +147,87 @@ export class ImagesPersistenceHandler {
150
147
  ): Promise<boolean> {
151
148
  try {
152
149
  if (!this._initialized) {
153
- await this.setup();
150
+ await this.setup()
154
151
  }
155
152
 
156
- this._logger.debug({ imageName }, 'Persisting image');
153
+ this._logger.debug({ imageName }, 'Persisting image')
157
154
 
158
- await this.createRoomFolder(imageName);
159
- await this.createRoomMimeTypeFolder(imageName);
155
+ await this.createRoomFolder(imageName)
156
+ await this.createRoomMimeTypeFolder(imageName)
160
157
 
161
- const filePath = path.join(process.cwd(), IMAGES_FOLDER, imageName);
158
+ const filePath = path.join(process.cwd(), IMAGES_FOLDER, imageName)
162
159
  const fileMimeTypePath = path.join(
163
160
  process.cwd(),
164
161
  IMAGES_MIME_TYPE_FOLDER,
165
162
  imageName
166
- );
167
- const filePathMimeType = `${fileMimeTypePath}.mimeType`;
163
+ )
164
+ const filePathMimeType = `${fileMimeTypePath}.mimeType`
168
165
 
169
166
  try {
170
- await fs.writeFile(filePathMimeType, mimeType, { encoding: 'utf-8' });
171
- await fs.writeFile(filePath, content);
167
+ await fs.writeFile(filePathMimeType, mimeType, { encoding: 'utf-8' })
168
+ await fs.writeFile(filePath, content)
172
169
 
173
- this._logger.debug({ imageName }, 'Persisted image');
170
+ this._logger.debug({ imageName }, 'Persisted image')
174
171
 
175
- return true;
172
+ return true
176
173
  } catch (err) {
177
- this._logger.error({ imageName, error: err }, 'Error saving the image');
178
- return false;
174
+ this._logger.error({ imageName, error: err }, 'Error saving the image')
175
+ return false
179
176
  }
180
177
  } catch (ex) {
181
- this._logger.error({ imageName, error: ex }, 'Error persisting image');
182
- return false;
178
+ this._logger.error({ imageName, error: ex }, 'Error persisting image')
179
+ return false
183
180
  }
184
181
  }
185
182
 
186
183
  async delete(imageName: string): Promise<boolean> {
187
184
  try {
188
185
  if (!this._initialized) {
189
- await this.setup();
186
+ await this.setup()
190
187
  }
191
188
 
192
189
  try {
193
- this._logger.debug({ imageName }, 'Deleting image');
190
+ this._logger.debug({ imageName }, 'Deleting image')
194
191
 
195
- await this.createRoomFolder(imageName);
196
- await this.createRoomMimeTypeFolder(imageName);
192
+ await this.createRoomFolder(imageName)
193
+ await this.createRoomMimeTypeFolder(imageName)
197
194
 
198
- const filePath = path.join(process.cwd(), IMAGES_FOLDER, imageName);
195
+ const filePath = path.join(process.cwd(), IMAGES_FOLDER, imageName)
199
196
  const fileMimeTypePath = path.join(
200
197
  process.cwd(),
201
198
  IMAGES_MIME_TYPE_FOLDER,
202
199
  imageName
203
- );
204
- const filePathMimeType = `${fileMimeTypePath}.mimeType`;
200
+ )
201
+ const filePathMimeType = `${fileMimeTypePath}.mimeType`
205
202
 
206
203
  if (!(await this.exists(imageName))) {
207
- this._logger.debug({ imageName }, 'Image not found');
208
- return false;
204
+ this._logger.debug({ imageName }, 'Image not found')
205
+ return false
209
206
  }
210
207
 
211
- await fs.unlink(filePath);
212
- await fs.unlink(filePathMimeType);
208
+ await fs.unlink(filePath)
209
+ await fs.unlink(filePathMimeType)
213
210
 
214
- this._logger.debug({ imageName }, 'Deleted image');
211
+ this._logger.debug({ imageName }, 'Deleted image')
215
212
 
216
- return true;
213
+ return true
217
214
  } catch (err) {
218
- this._logger.error(
219
- { imageName, error: err },
220
- 'Error deleting the file'
221
- );
222
- return false;
215
+ this._logger.error({ imageName, error: err }, 'Error deleting the file')
216
+ return false
223
217
  }
224
218
  } catch (ex) {
225
- this._logger.error({ imageName, error: ex }, 'Error deleting the image');
226
- return false;
219
+ this._logger.error({ imageName, error: ex }, 'Error deleting the image')
220
+ return false
227
221
  }
228
222
  }
229
223
 
230
224
  async getFilePath(imageName: string): Promise<string> {
231
225
  if (!this._initialized) {
232
- await this.setup();
226
+ await this.setup()
233
227
  }
234
228
 
235
- const filePath = path.join(process.cwd(), IMAGES_FOLDER, imageName);
229
+ const filePath = path.join(process.cwd(), IMAGES_FOLDER, imageName)
236
230
 
237
- return filePath;
231
+ return filePath
238
232
  }
239
233
  }
@@ -9,7 +9,9 @@ export const getFileContents = async (
9
9
  return content
10
10
  } catch (err) {
11
11
  console.error(
12
- `Error reading file ${filePath}: ${err instanceof Error ? err.message : err}`
12
+ `Error reading file ${filePath}: ${
13
+ err instanceof Error ? err.message : err
14
+ }`
13
15
  )
14
16
  throw err
15
17
  }
@@ -1 +0,0 @@
1
- {"version":3,"file":"create-app-C_sHOvXR.js","names":["cwd: string","root: string","manager: PackageManager","dest: string","options: Options","file: string","dest: string","projectName: string","from: string","to: string","rename: (s: string) => string","obj: T","keys: K[]","result: Partial<T>"],"sources":["../src/git.ts","../src/versions.js","../template/package.json","../src/auto-install.ts","../src/constants.ts","../src/create-app.ts"],"sourcesContent":["import { execSync } from 'node:child_process';\nimport { rmSync } from 'node:fs';\nimport { join } from 'node:path';\n\n/*\nInitialize a Git repo on the project.\n\nBased on https://github.com/vercel/next.js/blob/canary/packages/create-next-app/helpers/git.ts\n*/\n\nfunction isInGitRepository(cwd: string): boolean {\n try {\n execSync('git rev-parse --is-inside-work-tree', { stdio: 'ignore', cwd });\n return true;\n } catch {\n return false;\n }\n}\n\nfunction isInMercurialRepository(cwd: string): boolean {\n try {\n execSync('hg --cwd . root', { stdio: 'ignore', cwd });\n return true;\n } catch {\n return false;\n }\n}\n\nfunction isDefaultBranchSet(cwd: string): boolean {\n try {\n execSync('git config init.defaultBranch', { stdio: 'ignore', cwd });\n return true;\n } catch {\n return false;\n }\n}\n\nexport function tryGitInit(root: string): boolean {\n let didInit = false;\n\n try {\n execSync('git --version', { stdio: 'ignore' });\n if (isInGitRepository(root) || isInMercurialRepository(root)) {\n return false;\n }\n\n execSync('git init', { stdio: 'ignore', cwd: root });\n didInit = true;\n\n if (!isDefaultBranchSet(root)) {\n execSync('git checkout -b main', { stdio: 'ignore', cwd: root });\n }\n\n execSync('git add -A', { stdio: 'ignore', cwd: root });\n execSync('git commit -m \"Initial commit from Create Fumadocs App\"', {\n stdio: 'ignore',\n cwd: root,\n });\n return true;\n } catch {\n if (didInit) {\n try {\n rmSync(join(root, '.git'), { recursive: true, force: true });\n } catch {\n // do nothing\n }\n }\n\n return false;\n }\n}\n","export const versions = {\"@inditextech/weave-types\":\"0.23.0\",\"@inditextech/weave-sdk\":\"0.23.0\",\"@inditextech/weave-store-websockets\":\"0.23.0\",\"@inditextech/weave-store-azure-web-pubsub\":\"0.23.0\",\"@inditextech/weave-react\":\"0.23.0\"}","{\n \"name\": \"example-versions\",\n \"version\": \"0.0.0\",\n \"private\": true,\n \"description\": \"Used to track dependency versions in create-*-app\",\n \"license\": \"MIT\",\n \"dependencies\": {\n \"@dotenvx/dotenvx\": \"^1.44.0\",\n \"@imgly/background-removal-node\": \"^1.4.5\",\n \"@inditextech/weave-sdk\": \"0.0.0\",\n \"@inditextech/weave-store-websockets\": \"0.0.0\",\n \"@inditextech/weave-store-azure-web-pubsub\": \"0.0.0\",\n \"cors\": \"^2.8.5\",\n \"dotenv\": \"^16.4.7\",\n \"express\": \"^4.21.2\",\n \"helmet\": \"^8.0.0\",\n \"morgan\": \"^1.10.0\",\n \"multer\": \"^1.4.5-lts.1\",\n \"pino\": \"^9.6.0\",\n \"pino-http\": \"^10.4.0\",\n \"pino-pretty\": \"^13.0.0\",\n \"tslib\": \"^2.8.1\",\n \"tsx\": \"^4.19.3\",\n \"uuid\": \"^11.1.0\",\n \"zod\": \"^3.24.2\"\n },\n \"devDependencies\": {\n \"@eslint/js\": \"^9.26.0\",\n \"@types/cors\": \"^2.8.17\",\n \"@types/express\": \"^5.0.0\",\n \"@types/morgan\": \"^1.9.9\",\n \"@types/multer\": \"^1.4.12\",\n \"@types/node\": \"^22.13.5\",\n \"@typescript-eslint/eslint-plugin\": \"^8.25.0\",\n \"@typescript-eslint/parser\": \"^8.25.0\",\n \"cp-cli\": \"^2.0.0\",\n \"eslint\": \"^9.26.0\",\n \"eslint-config-prettier\": \"^10.1.5\",\n \"globals\": \"^16.0.0\",\n \"nodemon\": \"^3.1.9\",\n \"prettier\": \"^3.5.2\",\n \"tsc-alias\": \"^1.8.16\",\n \"tsconfig-paths\": \"^4.2.0\",\n \"typescript\": \"^5.7.3\",\n \"typescript-eslint\": \"^8.25.0\"\n }\n}\n","import { spawn } from 'cross-spawn';\n\nexport type PackageManager = 'npm' | 'pnpm' | 'yarn' | 'bun';\n\nexport function getPackageManager(): PackageManager {\n const userAgent = process.env.npm_config_user_agent ?? '';\n\n if (userAgent.startsWith('yarn')) {\n return 'yarn';\n }\n\n if (userAgent.startsWith('pnpm')) {\n return 'pnpm';\n }\n\n if (userAgent.startsWith('bun')) {\n return 'bun';\n }\n\n return 'npm';\n}\n\nexport function autoInstall(\n manager: PackageManager,\n dest: string,\n): Promise<void> {\n return new Promise((res, reject) => {\n const installProcess = spawn(manager, ['install'], {\n stdio: 'ignore',\n env: {\n ...process.env,\n NODE_ENV: 'development',\n DISABLE_OPENCOLLECTIVE: '1',\n },\n cwd: dest,\n });\n\n installProcess.on('close', (code) => {\n if (code !== 0) {\n reject(new Error('Install failed'));\n } else {\n res();\n }\n });\n });\n}\n","import { fileURLToPath } from 'node:url';\n\nexport const sourceDir = fileURLToPath(new URL(`../`, import.meta.url).href);\nexport const cwd = process.cwd();\n","import path from 'node:path';\nimport fs from 'node:fs/promises';\nimport { tryGitInit } from '@/git';\nimport { versions as localVersions } from '@/versions';\nimport versionPkg from './../template/package.json';\nimport type { PackageManager } from './auto-install';\nimport { autoInstall } from './auto-install';\nimport { cwd, sourceDir } from './constants';\n\nexport type Template = '+express+websockets' | '+express+azure-web-pubsub';\n\nexport interface Options {\n outputDir: string;\n template: Template;\n packageManager: PackageManager;\n installDeps?: boolean;\n initializeGit?: boolean;\n log?: (message: string) => void;\n}\n\nexport async function create(options: Options): Promise<void> {\n const {\n installDeps = true,\n initializeGit = true,\n log = console.log,\n } = options;\n const projectName = path.basename(options.outputDir);\n const dest = path.resolve(cwd, options.outputDir);\n\n function defaultRename(file: string): string {\n file = file.replace('example.gitignore', '.gitignore');\n file = file.replace('example.env', '.env');\n\n return file;\n }\n\n await copy(\n path.join(sourceDir, `template/${options.template}`),\n dest,\n defaultRename\n );\n\n // update tsconfig.json for src dir\n // if (isNext && options.useSrcDir) {\n const tsconfigPath = path.join(dest, 'tsconfig.json');\n const content = (await fs.readFile(tsconfigPath)).toString();\n\n const config = JSON.parse(content);\n\n if (config.compilerOptions?.paths) {\n Object.assign(config.compilerOptions.paths, {\n '@/*': ['./src/*'],\n });\n }\n\n await fs.writeFile(tsconfigPath, JSON.stringify(config, null, 2));\n // }\n\n const packageJson = createPackageJson(projectName, options);\n await fs.writeFile(\n path.join(dest, 'package.json'),\n JSON.stringify(packageJson, null, 2)\n );\n\n const readMe = await getReadme(dest, projectName);\n await fs.writeFile(path.join(dest, 'README.md'), readMe);\n\n if (installDeps) {\n await autoInstall(options.packageManager, dest);\n log('Installed dependencies');\n }\n\n if (initializeGit && tryGitInit(dest)) {\n log('Initialized Git repository');\n }\n}\n\nasync function getReadme(dest: string, projectName: string): Promise<string> {\n const template = await fs\n .readFile(path.join(dest, 'README.md'))\n .then((res) => res.toString());\n\n return `# ${projectName}\\n\\n${template}`;\n}\n\nasync function copy(\n from: string,\n to: string,\n rename: (s: string) => string = (s) => s\n): Promise<void> {\n const stats = await fs.stat(from);\n\n if (stats.isDirectory()) {\n const files = await fs.readdir(from);\n\n await Promise.all(\n files.map((file) =>\n copy(path.join(from, file), rename(path.join(to, file)))\n )\n );\n } else {\n await fs.mkdir(path.dirname(to), { recursive: true });\n await fs.copyFile(from, to);\n }\n}\n\nfunction createPackageJson(projectName: string, options: Options): object {\n if (options.template === '+express+azure-web-pubsub') {\n const dependencies = {\n ...pick(localVersions, [\n '@inditextech/weave-sdk',\n '@inditextech/weave-store-azure-web-pubsub',\n ]),\n ...pick(versionPkg.dependencies, [\n '@dotenvx/dotenvx',\n '@imgly/background-removal-node',\n 'cors',\n 'dotenv',\n 'express',\n 'helmet',\n 'morgan',\n 'multer',\n 'pino',\n 'pino-http',\n 'pino-pretty',\n 'tslib',\n 'tsx',\n 'uuid',\n 'zod',\n ]),\n };\n\n const devDependencies = {\n ...pick(versionPkg.devDependencies, [\n '@eslint/js',\n '@types/cors',\n '@types/express',\n '@types/morgan',\n '@types/multer',\n '@types/node',\n '@typescript-eslint/eslint-plugin',\n '@typescript-eslint/parser',\n 'cp-cli',\n 'eslint',\n 'eslint-config-prettier',\n 'globals',\n 'nodemon',\n 'prettier',\n 'tsc-alias',\n 'tsconfig-paths',\n 'typescript',\n 'typescript-eslint',\n ]),\n };\n\n return {\n name: projectName,\n type: 'module',\n scripts: {\n build:\n 'tsc && tsc-alias -p tsconfig.json && mkdir -p ./dist/public && mkdir -p ./dist/temp && cp-cli ./public ./dist/public && cp-cli ./package.json ./dist/package.json',\n copyAssets:\n 'mkdir -p ./public && cp-cli node_modules/@imgly/background-removal-node/dist/. public',\n dev: 'nodemon --exec \"dotenvx run -- tsx src/server.ts\"',\n format: 'prettier --write \"src/**/*.{ts,tsx}\"',\n lint: 'eslint ./src',\n postinstall: 'npm run copyAssets',\n start: 'dotenvx run -- tsx server.js',\n },\n private: true,\n dependencies: sortObjectKeys(dependencies),\n devDependencies: sortObjectKeys(devDependencies),\n };\n }\n\n const dependencies = {\n ...pick(versionPkg.dependencies, [\n '@dotenvx/dotenvx',\n '@imgly/background-removal-node',\n 'cors',\n 'dotenv',\n 'express',\n 'helmet',\n 'morgan',\n 'multer',\n 'pino',\n 'pino-http',\n 'pino-pretty',\n 'tslib',\n 'tsx',\n 'uuid',\n 'zod',\n ]),\n ...pick(localVersions, [\n '@inditextech/weave-sdk',\n '@inditextech/weave-store-websockets',\n ]),\n };\n\n const devDependencies = {\n ...pick(versionPkg.devDependencies, [\n '@eslint/js',\n '@types/cors',\n '@types/express',\n '@types/morgan',\n '@types/multer',\n '@types/node',\n '@typescript-eslint/eslint-plugin',\n '@typescript-eslint/parser',\n 'cp-cli',\n 'eslint',\n 'eslint-config-prettier',\n 'globals',\n 'nodemon',\n 'prettier',\n 'tsc-alias',\n 'tsconfig-paths',\n 'typescript',\n 'typescript-eslint',\n ]),\n };\n\n return {\n name: projectName,\n version: '0.0.0',\n private: true,\n scripts: {\n build:\n 'tsc && tsc-alias -p tsconfig.json && mkdir -p ./dist/public && mkdir -p ./dist/temp && cp-cli ./public ./dist/public && cp-cli ./package.json ./dist/package.json',\n copyAssets:\n 'mkdir -p ./public && cp-cli node_modules/@imgly/background-removal-node/dist/. public',\n dev: 'nodemon --exec \"dotenvx run -- tsx src/server.ts\"',\n format: 'prettier --write \"src/**/*.{ts,tsx}\"',\n lint: 'eslint ./src',\n postinstall: 'npm run copyAssets',\n start: 'dotenvx run -- tsx server.js',\n },\n dependencies: sortObjectKeys(dependencies),\n devDependencies: sortObjectKeys(devDependencies),\n };\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction sortObjectKeys<T extends Record<string, any>>(obj: T): T {\n const sortedEntries = Object.keys(obj)\n .sort()\n .map((key) => [key, obj[key]] as [keyof T, T[keyof T]]);\n\n return Object.fromEntries(sortedEntries) as T;\n}\n\nfunction pick<T extends object, K extends keyof T>(\n obj: T,\n keys: K[]\n): Pick<T, K> {\n const result: Partial<T> = {};\n\n for (const key of keys) {\n if (key in obj) {\n result[key] = obj[key];\n }\n }\n\n return result as Pick<T, K>;\n}\n"],"mappings":"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CA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;GACD,EAAC;EACH;EAED,MAAM,oBAAkB,EACtB,GAAG,KAAK,gBAAW,iBAAiB;GAClC;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACD,EAAC,CACH;AAED,SAAO;GACL,MAAM;GACN,MAAM;GACN,SAAS;IACP,OACE;IACF,YACE;IACF,KAAK;IACL,QAAQ;IACR,MAAM;IACN,aAAa;IACb,OAAO;GACR;GACD,SAAS;GACT,cAAc,eAAe,eAAa;GAC1C,iBAAiB,eAAe,kBAAgB;EACjD;CACF;CAED,MAAM,iBAAe;EACnB,GAAG,KAAK,gBAAW,cAAc;GAC/B;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACD,EAAC;EACF,GAAG,KAAK,UAAe,CACrB,0BACA,qCACD,EAAC;CACH;CAED,MAAM,oBAAkB,EACtB,GAAG,KAAK,gBAAW,iBAAiB;EAClC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACD,EAAC,CACH;AAED,QAAO;EACL,MAAM;EACN,SAAS;EACT,SAAS;EACT,SAAS;GACP,OACE;GACF,YACE;GACF,KAAK;GACL,QAAQ;GACR,MAAM;GACN,aAAa;GACb,OAAO;EACR;EACD,cAAc,eAAe,eAAa;EAC1C,iBAAiB,eAAe,kBAAgB;CACjD;AACF;AAGD,SAAS,eAA8CO,KAAW;CAChE,MAAM,gBAAgB,OAAO,KAAK,IAAI,CACnC,MAAM,CACN,IAAI,CAAC,QAAQ,CAAC,KAAK,IAAI,IAAK,EAA0B;AAEzD,QAAO,OAAO,YAAY,cAAc;AACzC;AAED,SAAS,KACPA,KACAC,MACY;CACZ,MAAMC,SAAqB,CAAE;AAE7B,MAAK,MAAM,OAAO,KAChB,KAAI,OAAO,IACT,QAAO,OAAO,IAAI;AAItB,QAAO;AACR"}