@stripchatdev/create-stripchat-extension 0.1.46 → 0.1.48

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.
Files changed (214) hide show
  1. package/dist/bin/cli/actions/updateAction.d.ts +6 -0
  2. package/dist/bin/cli/actions/updateAction.js +33 -0
  3. package/dist/bin/cli/helpers/printCliError.d.ts +1 -0
  4. package/dist/bin/cli/helpers/printCliError.js +21 -0
  5. package/dist/bin/cli/index.js +70 -0
  6. package/dist/bin/create.d.ts +2 -0
  7. package/dist/bin/create.js +246 -0
  8. package/dist/package.json +9 -4
  9. package/dist/src/constants.d.ts +14 -9
  10. package/dist/src/constants.js +73 -12
  11. package/dist/src/dependencies/constants.d.ts +2 -0
  12. package/dist/src/dependencies/constants.js +11 -0
  13. package/dist/src/dependencies/resolveDependencies.d.ts +6 -0
  14. package/dist/src/dependencies/resolveDependencies.js +43 -0
  15. package/dist/src/dependencies/resolveDependencies.test.js +74 -0
  16. package/dist/src/helpers/error.d.ts +3 -0
  17. package/dist/src/helpers/error.js +9 -0
  18. package/dist/src/helpers/error.test.js +15 -0
  19. package/dist/src/helpers/getIsDirectoryExists.d.ts +7 -0
  20. package/dist/src/helpers/getIsDirectoryExists.js +23 -0
  21. package/dist/src/helpers/getIsDirectoryExists.test.js +34 -0
  22. package/dist/src/helpers/getIsJsxFramework.d.ts +2 -0
  23. package/dist/src/helpers/getIsJsxFramework.js +2 -0
  24. package/dist/src/helpers/getIsJsxFramework.test.js +10 -0
  25. package/dist/src/helpers/getIsTypescript.d.ts +2 -0
  26. package/dist/src/helpers/getIsTypescript.js +1 -0
  27. package/dist/src/helpers/getIsTypescript.test.js +10 -0
  28. package/dist/src/helpers/isSubPath.d.ts +1 -0
  29. package/dist/src/helpers/isSubPath.js +5 -0
  30. package/dist/src/helpers/normalizePath.d.ts +2 -0
  31. package/dist/src/helpers/normalizePath.js +4 -0
  32. package/dist/src/helpers/normalizePath.test.js +19 -0
  33. package/dist/src/migrator/executor.d.ts +9 -0
  34. package/dist/src/migrator/executor.js +112 -0
  35. package/dist/src/migrator/migration.d.ts +3 -0
  36. package/dist/src/migrator/migration.js +18 -0
  37. package/dist/src/migrator/migration.test.js +74 -0
  38. package/dist/src/migrator/migrations/migrations.test.js +97 -0
  39. package/dist/src/migrator/migrations/v2/AGENTS_md/001_recreate-with-generated-part.d.ts +2 -0
  40. package/dist/src/migrator/migrations/v2/AGENTS_md/001_recreate-with-generated-part.js +14 -0
  41. package/dist/src/migrator/migrations/v2/_project-config_json/001_create.d.ts +2 -0
  42. package/dist/src/migrator/migrations/v2/_project-config_json/001_create.js +14 -0
  43. package/dist/src/migrator/migrations/v2/vite_config_ts/001_turn_off_minify_and_assets_inline.d.ts +2 -0
  44. package/dist/src/migrator/migrations/v2/vite_config_ts/001_turn_off_minify_and_assets_inline.js +118 -0
  45. package/dist/src/migrator/planner.d.ts +5 -0
  46. package/dist/src/migrator/planner.js +65 -0
  47. package/dist/src/migrator/planner.test.js +40 -0
  48. package/dist/src/migrator/types.d.ts +29 -0
  49. package/dist/src/migrator/updates/updates.test.js +102 -0
  50. package/dist/src/migrator/updates/v2/AGENTS_md/001_update-generated-part.d.ts +2 -0
  51. package/dist/src/migrator/updates/v2/AGENTS_md/001_update-generated-part.js +38 -0
  52. package/dist/src/migrator/updates/v2/package_json/001_update-versions.d.ts +2 -0
  53. package/dist/src/migrator/updates/v2/package_json/001_update-versions.js +77 -0
  54. package/dist/src/migrator/updates/v2/package_json/002_add-cli-commands.d.ts +2 -0
  55. package/dist/src/migrator/updates/v2/package_json/002_add-cli-commands.js +61 -0
  56. package/dist/src/migrator/validators/getIsValidMigration.d.ts +2 -0
  57. package/dist/src/migrator/validators/getIsValidMigration.js +3 -0
  58. package/dist/src/migrator/validators/getIsValidMigration.test.js +13 -0
  59. package/dist/src/projectConfig/buildProjectConfig.d.ts +15 -0
  60. package/dist/src/projectConfig/buildProjectConfig.js +27 -0
  61. package/dist/src/projectConfig/detectPackageManagerRuntime.d.ts +2 -0
  62. package/dist/src/{helpers/detectPackageManager.js → projectConfig/detectPackageManagerRuntime.js} +1 -1
  63. package/dist/src/{helpers/detectPackageManager.test.js → projectConfig/detectPackageManagerRuntime.test.js} +10 -10
  64. package/dist/src/projectConfig/recoverProjectConfig.d.ts +1 -0
  65. package/dist/src/projectConfig/recoverProjectConfig.js +34 -0
  66. package/dist/src/projectConfig/recovery/detectPackageManagerFromFiles.d.ts +2 -0
  67. package/dist/src/projectConfig/recovery/detectPackageManagerFromFiles.js +16 -0
  68. package/dist/src/projectConfig/recovery/detectPackageManagerFromFiles.test.d.ts +1 -0
  69. package/dist/src/projectConfig/recovery/detectPackageManagerFromFiles.test.js +37 -0
  70. package/dist/src/projectConfig/recovery/parseAgentsMd.d.ts +10 -0
  71. package/dist/src/projectConfig/recovery/parseAgentsMd.js +52 -0
  72. package/dist/src/projectConfig/recovery/parseAgentsMd.test.d.ts +1 -0
  73. package/dist/src/projectConfig/recovery/parseAgentsMd.test.js +67 -0
  74. package/dist/src/projectConfig/recovery/resolveProjectNameFromDir.d.ts +1 -0
  75. package/dist/src/projectConfig/recovery/resolveProjectNameFromDir.js +11 -0
  76. package/dist/src/projectConfig/recovery/resolveProjectNameFromDir.test.d.ts +1 -0
  77. package/dist/src/projectConfig/recovery/resolveProjectNameFromDir.test.js +21 -0
  78. package/dist/src/projectConfig/resolveExistsProjectConfig.d.ts +2 -0
  79. package/dist/src/projectConfig/resolveExistsProjectConfig.js +34 -0
  80. package/dist/src/projectConfig/updateProjectConfig.d.ts +2 -0
  81. package/dist/src/projectConfig/updateProjectConfig.js +20 -0
  82. package/dist/src/projectConfig/validators/getIsValidProjectConfig.d.ts +2 -0
  83. package/dist/src/projectConfig/validators/getIsValidProjectConfig.js +6 -0
  84. package/dist/src/projectConfig/validators/getIsValidProjectConfig.test.d.ts +1 -0
  85. package/dist/src/projectConfig/validators/getIsValidProjectConfig.test.js +33 -0
  86. package/dist/src/projectConfig/validators/validateProjectConfig.d.ts +2 -0
  87. package/dist/src/projectConfig/validators/validateProjectConfig.js +30 -0
  88. package/dist/src/projectConfig/validators/validateProjectConfig.test.d.ts +1 -0
  89. package/dist/src/projectConfig/validators/validateProjectConfig.test.js +215 -0
  90. package/dist/src/templater/executor.d.ts +2 -0
  91. package/dist/src/templater/executor.js +22 -0
  92. package/dist/src/templater/executor.test.d.ts +1 -0
  93. package/dist/src/{executor.test.js → templater/executor.test.js} +25 -11
  94. package/dist/src/templater/helpers/getIsTypescriptOnlyFile.d.ts +1 -0
  95. package/dist/src/templater/helpers/getIsTypescriptOnlyFile.js +10 -0
  96. package/dist/src/templater/helpers/getIsTypescriptOnlyFile.test.d.ts +1 -0
  97. package/dist/src/templater/helpers/getIsTypescriptOnlyFile.test.js +25 -0
  98. package/dist/src/templater/helpers/resolveTemplateExtension.d.ts +1 -0
  99. package/dist/src/templater/helpers/resolveTemplateExtension.js +16 -0
  100. package/dist/src/templater/helpers/resolveTemplateExtension.test.d.ts +1 -0
  101. package/dist/src/{mappers → templater/mappers}/mapProjectConfigToTemplateModel.d.ts +1 -1
  102. package/dist/src/{mappers → templater/mappers}/mapProjectConfigToTemplateModel.js +6 -8
  103. package/dist/src/templater/mappers/mapProjectConfigToTemplateModel.test.d.ts +1 -0
  104. package/dist/src/{mappers → templater/mappers}/mapProjectConfigToTemplateModel.test.js +29 -23
  105. package/dist/src/templater/planner.d.ts +2 -0
  106. package/dist/src/templater/planner.js +104 -0
  107. package/dist/src/templater/planner.test.d.ts +1 -0
  108. package/dist/src/templater/planner.test.js +64 -0
  109. package/dist/src/templates/constants.d.ts +6 -0
  110. package/dist/src/templates/constants.js +11 -0
  111. package/dist/src/templates/helpers/resolveTemplatesDir.d.ts +1 -0
  112. package/dist/src/templates/helpers/resolveTemplatesDir.js +16 -0
  113. package/dist/src/templates/templates.d.ts +10 -0
  114. package/dist/src/templates/templates.js +133 -0
  115. package/dist/src/templates/templates.test.d.ts +1 -0
  116. package/dist/src/templates/templates.test.js +263 -0
  117. package/dist/src/templates/types.d.ts +21 -0
  118. package/dist/src/templates/types.js +1 -0
  119. package/dist/src/types.d.ts +28 -9
  120. package/dist/src/validators/getIsValidCategory.d.ts +2 -0
  121. package/dist/src/validators/getIsValidCategory.js +2 -0
  122. package/dist/src/validators/getIsValidCategory.test.d.ts +1 -0
  123. package/dist/src/validators/{isValidCategory.test.js → getIsValidCategory.test.js} +3 -3
  124. package/dist/src/validators/getIsValidFramework.d.ts +2 -0
  125. package/dist/src/validators/getIsValidFramework.js +2 -0
  126. package/dist/src/validators/getIsValidFramework.test.d.ts +1 -0
  127. package/dist/src/validators/{isValidFramework.test.js → getIsValidFramework.test.js} +3 -3
  128. package/dist/src/validators/getIsValidLanguage.d.ts +2 -0
  129. package/dist/src/validators/getIsValidLanguage.js +2 -0
  130. package/dist/src/validators/getIsValidLanguage.test.d.ts +1 -0
  131. package/dist/src/validators/{isValidLanguage.test.js → getIsValidLanguage.test.js} +3 -3
  132. package/dist/src/validators/getIsValidPackageManager.d.ts +2 -0
  133. package/dist/src/validators/getIsValidPackageManager.js +4 -0
  134. package/dist/src/validators/getIsValidPackageManager.test.d.ts +1 -0
  135. package/dist/src/validators/getIsValidPackageManager.test.js +11 -0
  136. package/dist/src/validators/getIsValidSlot.d.ts +2 -0
  137. package/dist/src/validators/getIsValidSlot.js +4 -0
  138. package/dist/src/validators/getIsValidSlot.test.d.ts +1 -0
  139. package/dist/src/validators/getIsValidSlot.test.js +26 -0
  140. package/dist/src/validators/validateSlots.js +40 -8
  141. package/dist/src/validators/validateSlots.test.js +125 -34
  142. package/dist/tsconfig.tsbuildinfo +1 -1
  143. package/package.json +9 -4
  144. package/templates/v1/vite.config.ts.ejs +27 -0
  145. package/templates/v2/.project-config.json.ejs +1 -0
  146. package/templates/v2/AGENTS.md.ejs +712 -0
  147. package/templates/v2/README.md.ejs +31 -0
  148. package/templates/v2/package.json.ejs +26 -0
  149. package/dist/bin/cli.js +0 -221
  150. package/dist/src/executor.d.ts +0 -2
  151. package/dist/src/executor.js +0 -22
  152. package/dist/src/helpers/detectPackageManager.d.ts +0 -2
  153. package/dist/src/helpers/isDirectory.d.ts +0 -1
  154. package/dist/src/helpers/isDirectory.js +0 -9
  155. package/dist/src/helpers/isDirectory.test.js +0 -22
  156. package/dist/src/helpers/isTypescriptOnlyFile.d.ts +0 -1
  157. package/dist/src/helpers/isTypescriptOnlyFile.js +0 -5
  158. package/dist/src/helpers/isTypescriptOnlyFile.test.js +0 -22
  159. package/dist/src/helpers/normalizeRelPath.d.ts +0 -1
  160. package/dist/src/helpers/normalizeRelPath.js +0 -1
  161. package/dist/src/helpers/normalizeRelPath.test.js +0 -19
  162. package/dist/src/helpers/resolveTemplateExtension.d.ts +0 -1
  163. package/dist/src/helpers/resolveTemplateExtension.js +0 -17
  164. package/dist/src/helpers/resolveTemplatesDir.d.ts +0 -1
  165. package/dist/src/helpers/resolveTemplatesDir.js +0 -11
  166. package/dist/src/helpers/resolveTemplatesDir.test.js +0 -21
  167. package/dist/src/planner.d.ts +0 -2
  168. package/dist/src/planner.js +0 -126
  169. package/dist/src/planner.test.js +0 -58
  170. package/dist/src/validators/index.d.ts +0 -6
  171. package/dist/src/validators/index.js +0 -6
  172. package/dist/src/validators/isValidCategory.d.ts +0 -2
  173. package/dist/src/validators/isValidCategory.js +0 -2
  174. package/dist/src/validators/isValidFramework.d.ts +0 -2
  175. package/dist/src/validators/isValidFramework.js +0 -2
  176. package/dist/src/validators/isValidLanguage.d.ts +0 -2
  177. package/dist/src/validators/isValidLanguage.js +0 -2
  178. package/dist/src/validators/validateProjectDir.d.ts +0 -1
  179. package/dist/src/validators/validateProjectDir.js +0 -6
  180. package/dist/src/validators/validateProjectDir.test.js +0 -19
  181. package/dist/bin/{cli.d.ts → cli/index.d.ts} +0 -0
  182. package/dist/src/{executor.test.d.ts → dependencies/resolveDependencies.test.d.ts} +0 -0
  183. package/dist/src/helpers/{detectPackageManager.test.d.ts → error.test.d.ts} +0 -0
  184. package/dist/src/helpers/{isDirectory.test.d.ts → getIsDirectoryExists.test.d.ts} +0 -0
  185. package/dist/src/helpers/{isTypescriptOnlyFile.test.d.ts → getIsJsxFramework.test.d.ts} +0 -0
  186. package/dist/src/helpers/{normalizeRelPath.test.d.ts → getIsTypescript.test.d.ts} +0 -0
  187. package/dist/src/helpers/{resolveTemplateExtension.test.d.ts → normalizePath.test.d.ts} +0 -0
  188. package/dist/src/{helpers/resolveTemplatesDir.test.d.ts → migrator/migration.test.d.ts} +0 -0
  189. package/dist/src/{mappers/mapProjectConfigToTemplateModel.test.d.ts → migrator/migrations/migrations.test.d.ts} +0 -0
  190. package/dist/src/{planner.test.d.ts → migrator/planner.test.d.ts} +0 -0
  191. package/dist/src/{validators/isValidCategory.test.d.ts → migrator/types.js} +0 -0
  192. package/dist/src/{validators/isValidFramework.test.d.ts → migrator/updates/updates.test.d.ts} +0 -0
  193. package/dist/src/{validators/isValidLanguage.test.d.ts → migrator/validators/getIsValidMigration.test.d.ts} +0 -0
  194. package/dist/src/{validators/validateProjectDir.test.d.ts → projectConfig/detectPackageManagerRuntime.test.d.ts} +0 -0
  195. package/dist/src/{helpers → templater/helpers}/resolveTemplateExtension.test.js +0 -0
  196. package/templates/{.gitignore.ejs → v1/.gitignore.ejs} +0 -0
  197. package/templates/{AGENTS.md.ejs → v1/AGENTS.md.ejs} +0 -0
  198. package/templates/{CLAUDE.md → v1/CLAUDE.md} +0 -0
  199. package/templates/{README.md.ejs → v1/README.md.ejs} +0 -0
  200. package/templates/{package.json.ejs → v1/package.json.ejs} +0 -0
  201. package/templates/{public → v1/public}/icon.svg +0 -0
  202. package/templates/{public → v1/public}/manifest.json.ejs +0 -0
  203. package/templates/{public → v1/public}/resolveSlotPage.js.ejs +0 -0
  204. package/templates/{src → v1/src}/slots/background/app.ts.ejs +0 -0
  205. package/templates/{src → v1/src}/slots/background/background.html.ejs +0 -0
  206. package/templates/{src → v1/src}/slots/background/main.ts.ejs +0 -0
  207. package/templates/{src/slots/slot/slot.html.ejs → v1/src/slots/slot/__SLOT_KEY__.html.ejs} +0 -0
  208. package/templates/{src → v1/src}/slots/slot/app.ts.ejs +0 -0
  209. package/templates/{src → v1/src}/slots/slot/app.tsx.ejs +0 -0
  210. package/templates/{src → v1/src}/slots/slot/main.css.ejs +0 -0
  211. package/templates/{src → v1/src}/slots/slot/main.ts.ejs +0 -0
  212. package/templates/{src → v1/src}/slots/slot/main.tsx.ejs +0 -0
  213. package/templates/{tsconfig.json.ejs → v1/tsconfig.json.ejs} +0 -0
  214. package/templates/{vite.config.ts.ejs → v2/vite.config.ts.ejs} +1 -1
@@ -0,0 +1,64 @@
1
+ import { relative, basename, join } from 'node:path';
2
+ import { describe, expect, it } from 'vitest';
3
+ import { CATEGORIES, CLI_COMMANDS_MAP, EXT_HELPER_VERSION, FRAMEWORKS, LANGUAGES, SLOT_RULES_BY_CATEGORY, } from '../constants.js';
4
+ import { toNormalizedRelPath } from '../helpers/normalizePath.js';
5
+ import { buildProjectConfig } from '../projectConfig/buildProjectConfig.js';
6
+ import { MANAGED_TEMPLATES } from '../templates/constants.js';
7
+ import { LAST_TEMPLATE_VERSION, TEMPLATES_DIR } from '../templates/templates.js';
8
+ import { mapProjectConfigToTemplateData } from './mappers/mapProjectConfigToTemplateModel.js';
9
+ import { planProject } from './planner.js';
10
+ const PROJECT_DIR = '/output/my-ext';
11
+ const buildSlotCombos = (category) => {
12
+ const rules = SLOT_RULES_BY_CATEGORY[category];
13
+ const base = [...rules.requiredBase];
14
+ const combos = [base];
15
+ if (category === 'games-and-fun') {
16
+ combos.length = 0;
17
+ combos.push([...base, 'EXTENSION_SLOT_RIGHT_OVERLAY'], [...base, 'EXTENSION_SLOT_VIDEO_DECORATIVE_OVERLAY']);
18
+ return combos;
19
+ }
20
+ if (category === 'sex-toys') {
21
+ combos.push([...base, 'EXTENSION_SLOT_MOVEABLE_OVERLAY'], [...base, 'EXTENSION_SLOT_RIGHT_OVERLAY'], [...base, 'EXTENSION_SLOT_VIDEO_DECORATIVE_OVERLAY'], [...base, 'EXTENSION_SLOT_MOVEABLE_OVERLAY', 'EXTENSION_SLOT_RIGHT_OVERLAY'], [...base, 'EXTENSION_SLOT_MOVEABLE_OVERLAY', 'EXTENSION_SLOT_VIDEO_DECORATIVE_OVERLAY']);
22
+ }
23
+ return combos;
24
+ };
25
+ const SLOT_COMBOS_BY_CATEGORY = Object.fromEntries(CATEGORIES.map((category) => {
26
+ return [category, buildSlotCombos(category)];
27
+ }));
28
+ const TEST_CASES = CATEGORIES.flatMap((category) => SLOT_COMBOS_BY_CATEGORY[category].flatMap((slots) => FRAMEWORKS.flatMap((framework) => LANGUAGES.flatMap((language) => new Array(LAST_TEMPLATE_VERSION).fill(0).map((_, index) => ({
29
+ category,
30
+ framework,
31
+ language,
32
+ slots,
33
+ slotsStr: slots.join(', '),
34
+ templateVersion: index + 1,
35
+ }))))));
36
+ const normalizeCommands = (commands) => commands.map((cmd) => {
37
+ const srcRel = join(basename(TEMPLATES_DIR), relative(TEMPLATES_DIR, cmd.srcPath));
38
+ const srcNormalized = toNormalizedRelPath(srcRel);
39
+ const destNormalized = toNormalizedRelPath(cmd.destPath).replace('/output/', '');
40
+ if (cmd.type === 'copy') {
41
+ return { type: 'copy', src: srcNormalized, dest: destNormalized };
42
+ }
43
+ return { type: 'render', src: srcNormalized, dest: destNormalized };
44
+ });
45
+ describe('planProject', { tags: ['snapshot'] }, () => {
46
+ it.each(TEST_CASES)('template version $templateVersion + $language + $framework, $category ($slotsStr)', ({ category, framework, language, slots, templateVersion, }) => {
47
+ const projectConfig = buildProjectConfig({
48
+ category,
49
+ framework,
50
+ language,
51
+ name: basename(PROJECT_DIR),
52
+ packageManager: 'npm',
53
+ slots,
54
+ extHelperVersion: EXT_HELPER_VERSION,
55
+ lastTemplateVersion: templateVersion,
56
+ cliCommands: CLI_COMMANDS_MAP,
57
+ managedTemplates: MANAGED_TEMPLATES,
58
+ templatesDir: TEMPLATES_DIR,
59
+ });
60
+ const data = mapProjectConfigToTemplateData(projectConfig);
61
+ const commands = planProject(PROJECT_DIR, templateVersion, data);
62
+ expect(normalizeCommands(commands)).toMatchSnapshot();
63
+ });
64
+ });
@@ -0,0 +1,6 @@
1
+ import type { TRelPath } from '../types.js';
2
+ export declare const INIT_TEMPLATE_VERSION = 1;
3
+ export declare const TEMPLATE_EXT = ".ejs";
4
+ export declare const MANAGED_TEMPLATES: TRelPath[];
5
+ export declare const DELETED_TEMPLATE_EXT = ".deleted";
6
+ export declare const GENERAL_SLOT_NAME_PLACEHOLDER = "__SLOT_KEY__";
@@ -0,0 +1,11 @@
1
+ export const INIT_TEMPLATE_VERSION = 1;
2
+ export const TEMPLATE_EXT = '.ejs';
3
+ // only extends
4
+ export const MANAGED_TEMPLATES = [
5
+ 'AGENTS.md.ejs',
6
+ 'package.json.ejs',
7
+ 'vite.config.ts.ejs',
8
+ '.project-config.json.ejs',
9
+ ];
10
+ export const DELETED_TEMPLATE_EXT = '.deleted';
11
+ export const GENERAL_SLOT_NAME_PLACEHOLDER = '__SLOT_KEY__';
@@ -0,0 +1 @@
1
+ export declare const resolveTemplatesDir: () => string;
@@ -0,0 +1,16 @@
1
+ import { dirname, join } from 'node:path';
2
+ import { AppError } from '../../helpers/error.js';
3
+ import { getIsDirectoryExists } from '../../helpers/getIsDirectoryExists.js';
4
+ const __dirname = dirname(import.meta.filename);
5
+ export const resolveTemplatesDir = () => {
6
+ // First value resolves from dist/src/templates/helpers; second resolves from src/templates/helpers.
7
+ const candidatePaths = ['../../../../templates', '../../../templates'];
8
+ for (const candidatePath of candidatePaths) {
9
+ const dir = join(__dirname, candidatePath);
10
+ const { isExists } = getIsDirectoryExists(dir);
11
+ if (isExists) {
12
+ return dir;
13
+ }
14
+ }
15
+ throw new AppError('Templates dir not found');
16
+ };
@@ -0,0 +1,10 @@
1
+ import type { TRelPath } from '../types.js';
2
+ import type { TTemplateFile, TTemplateVersionDir, TManagedFile } from './types';
3
+ export declare const discoverVersionDirs: (templatesDir: string, targetVersion: number, order?: "asc" | "desc") => TTemplateVersionDir[];
4
+ export declare const getLastTemplateVersion: (templatesDir: string) => number;
5
+ export declare const collectManagedFiles: (templateDir: string, managedTemplates: TRelPath[], targetVersion: number) => TManagedFile[];
6
+ export declare const collectTemplateFiles: (templatesDir: string, targetVersion: number, subDir?: string) => TTemplateFile[];
7
+ export declare const TEMPLATES_DIR: string;
8
+ export declare const LAST_TEMPLATE_VERSION: number;
9
+ export declare const SLOTS_TEMPLATE_DIR_REL: string;
10
+ export declare const GENERAL_SLOT_TEMPLATE_DIR_REL: string;
@@ -0,0 +1,133 @@
1
+ import { existsSync, readdirSync } from 'node:fs';
2
+ import { join, relative } from 'node:path';
3
+ import { DELETED_TEMPLATE_EXT, INIT_TEMPLATE_VERSION, TEMPLATE_EXT } from './constants.js';
4
+ import { resolveTemplatesDir } from './helpers/resolveTemplatesDir.js';
5
+ const FOLDER_VERSION_PATTERN = /v(\d+)/;
6
+ export const discoverVersionDirs = (templatesDir, targetVersion, order = 'asc') => {
7
+ const entries = readdirSync(templatesDir, {
8
+ withFileTypes: true,
9
+ });
10
+ return entries
11
+ .map((entry) => {
12
+ if (!entry.isDirectory()) {
13
+ return null;
14
+ }
15
+ const match = entry.name.match(FOLDER_VERSION_PATTERN);
16
+ if (!match) {
17
+ return null;
18
+ }
19
+ const [, versionStr] = match;
20
+ const version = Number(versionStr);
21
+ if (!Number.isFinite(version)) {
22
+ return null;
23
+ }
24
+ if (version > targetVersion) {
25
+ return null;
26
+ }
27
+ return {
28
+ dirPath: join(entry.parentPath, entry.name),
29
+ version,
30
+ };
31
+ })
32
+ .filter((entry) => entry !== null)
33
+ .sort((a, b) => {
34
+ if (order === 'asc') {
35
+ return a.version - b.version;
36
+ }
37
+ return b.version - a.version;
38
+ });
39
+ };
40
+ export const getLastTemplateVersion = (templatesDir) => {
41
+ const versionDirs = discoverVersionDirs(templatesDir, Number.MAX_SAFE_INTEGER, 'desc');
42
+ return versionDirs[0]?.version || INIT_TEMPLATE_VERSION;
43
+ };
44
+ export const collectManagedFiles = (templateDir, managedTemplates, targetVersion) => {
45
+ const versionDirs = discoverVersionDirs(templateDir, targetVersion, 'asc');
46
+ const managedTemplatesMap = {};
47
+ for (const relPath of managedTemplates) {
48
+ for (const versionDir of versionDirs) {
49
+ const { dirPath, version } = versionDir;
50
+ const targetManagedFilePath = join(dirPath, relPath);
51
+ const targetManagedFilePathDeleted = join(dirPath, `${relPath}.deleted`);
52
+ if (existsSync(targetManagedFilePath)) {
53
+ managedTemplatesMap[relPath] = {
54
+ relPath,
55
+ srcPath: join(dirPath, relPath),
56
+ version,
57
+ };
58
+ }
59
+ else if (existsSync(targetManagedFilePathDeleted)) {
60
+ managedTemplatesMap[relPath] = {
61
+ relPath,
62
+ srcPath: join(dirPath, relPath),
63
+ version,
64
+ deleted: true,
65
+ };
66
+ }
67
+ }
68
+ }
69
+ return Object.values(managedTemplatesMap).map(({ deleted, relPath, version }) => {
70
+ return {
71
+ relPath: relPath.endsWith(TEMPLATE_EXT)
72
+ ? relPath.slice(0, -TEMPLATE_EXT.length)
73
+ : relPath,
74
+ version,
75
+ deleted,
76
+ };
77
+ });
78
+ };
79
+ const listTemplateFiles = (dir, version) => {
80
+ if (!existsSync(dir)) {
81
+ return [];
82
+ }
83
+ const entries = readdirSync(dir, { recursive: true, withFileTypes: true });
84
+ return entries
85
+ .filter((entry) => entry.isFile())
86
+ .map((entry) => {
87
+ const relPath = relative(dir, join(entry.parentPath, entry.name));
88
+ const srcPath = join(entry.parentPath, entry.name);
89
+ const isDeleted = relPath.endsWith(DELETED_TEMPLATE_EXT);
90
+ const resolvedRelPath = isDeleted
91
+ ? relPath.slice(0, -DELETED_TEMPLATE_EXT.length)
92
+ : relPath;
93
+ const resolvedSrcPath = isDeleted
94
+ ? srcPath.slice(0, -DELETED_TEMPLATE_EXT.length)
95
+ : srcPath;
96
+ return {
97
+ relPath: resolvedRelPath,
98
+ srcPath: resolvedSrcPath,
99
+ version,
100
+ deleted: isDeleted,
101
+ };
102
+ })
103
+ .sort((a, b) => a.relPath.localeCompare(b.relPath));
104
+ };
105
+ export const collectTemplateFiles = (templatesDir, targetVersion, subDir) => {
106
+ const versionDirs = discoverVersionDirs(templatesDir, targetVersion);
107
+ let subVersionDirs = versionDirs;
108
+ if (subDir) {
109
+ subVersionDirs = versionDirs.map(({ dirPath, version }) => {
110
+ return {
111
+ dirPath: join(dirPath, subDir),
112
+ version,
113
+ };
114
+ });
115
+ }
116
+ const templateFilesMap = {};
117
+ for (const { dirPath, version } of subVersionDirs) {
118
+ const templateFiles = listTemplateFiles(dirPath, version);
119
+ for (const templateFile of templateFiles) {
120
+ if (templateFile.deleted) {
121
+ delete templateFilesMap[templateFile.relPath];
122
+ }
123
+ else {
124
+ templateFilesMap[templateFile.relPath] = templateFile;
125
+ }
126
+ }
127
+ }
128
+ return Object.values(templateFilesMap);
129
+ };
130
+ export const TEMPLATES_DIR = resolveTemplatesDir();
131
+ export const LAST_TEMPLATE_VERSION = getLastTemplateVersion(TEMPLATES_DIR);
132
+ export const SLOTS_TEMPLATE_DIR_REL = join('src', 'slots');
133
+ export const GENERAL_SLOT_TEMPLATE_DIR_REL = join(SLOTS_TEMPLATE_DIR_REL, 'slot');
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,263 @@
1
+ import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs';
2
+ import { tmpdir } from 'node:os';
3
+ import { join } from 'node:path';
4
+ import { describe, expect, it } from 'vitest';
5
+ import { toNormalizedRelPath } from '../helpers/normalizePath.js';
6
+ import { discoverVersionDirs, collectManagedFiles, collectTemplateFiles } from './templates.js';
7
+ const getVersionsFromDirs = (dirs) => dirs.map(({ version }) => version);
8
+ const sortManagedFiles = (files) => [...files].sort((a, b) => a.relPath.localeCompare(b.relPath));
9
+ const normalizeCollectedManagedFiles = (files) => sortManagedFiles(files).map((file) => ({
10
+ ...file,
11
+ deleted: file.deleted === true,
12
+ relPath: toNormalizedRelPath(file.relPath),
13
+ }));
14
+ const normalizeExpectedManagedFiles = (files) => sortManagedFiles(files).map((file) => ({
15
+ ...file,
16
+ deleted: file.deleted === true,
17
+ }));
18
+ const sortTemplateFiles = (files) => [...files].sort((a, b) => a.relPath.localeCompare(b.relPath));
19
+ const normalizeCollectedTemplateFiles = (files) => sortTemplateFiles(files).map((file) => ({
20
+ ...file,
21
+ deleted: file.deleted === true,
22
+ relPath: toNormalizedRelPath(file.relPath),
23
+ }));
24
+ const normalizeExpectedTemplateFiles = (files) => sortTemplateFiles(files).map((file) => ({
25
+ ...file,
26
+ deleted: file.deleted === true,
27
+ }));
28
+ describe('discoverVersionDirs', () => {
29
+ it('discover only version dirs in correct order', () => {
30
+ const templatesDir = mkdtempSync(join(tmpdir(), 'sce-template-versions-'));
31
+ try {
32
+ mkdirSync(join(templatesDir, 'v2'));
33
+ mkdirSync(join(templatesDir, 'v10'));
34
+ mkdirSync(join(templatesDir, 'v1'));
35
+ mkdirSync(join(templatesDir, 'draft'));
36
+ writeFileSync(join(templatesDir, 'v3.txt'), 'not a directory');
37
+ const ascResult = discoverVersionDirs(templatesDir, 10, 'asc');
38
+ const descResult = discoverVersionDirs(templatesDir, 10, 'desc');
39
+ const limitedResult = discoverVersionDirs(templatesDir, 2, 'asc');
40
+ expect(getVersionsFromDirs(ascResult)).toEqual([1, 2, 10]);
41
+ expect(getVersionsFromDirs(descResult)).toEqual([10, 2, 1]);
42
+ expect(getVersionsFromDirs(limitedResult)).toEqual([1, 2]);
43
+ expect(ascResult.every(({ dirPath }) => dirPath.startsWith(templatesDir))).toBe(true);
44
+ }
45
+ finally {
46
+ rmSync(templatesDir, { recursive: true, force: true });
47
+ }
48
+ });
49
+ });
50
+ describe('collectManagedFiles', () => {
51
+ it('selects files from highest available version up to targetVersion', () => {
52
+ const templatesDir = mkdtempSync(join(tmpdir(), 'sce-collectManagedFiles-'));
53
+ try {
54
+ // v1: package.json, AGENTS.md, .project-config.json
55
+ mkdirSync(join(templatesDir, 'v1'));
56
+ writeFileSync(join(templatesDir, 'v1', 'package.json.ejs'), '{}');
57
+ writeFileSync(join(templatesDir, 'v1', 'AGENTS.md.ejs'), 'agents v1');
58
+ writeFileSync(join(templatesDir, 'v1', '.project-config.json.ejs'), '{}');
59
+ writeFileSync(join(templatesDir, 'v1', 'README.md'), 'readme v1');
60
+ mkdirSync(join(templatesDir, 'v2'));
61
+ writeFileSync(join(templatesDir, 'v2', 'vite.config.ts.ejs'), 'export default {}');
62
+ writeFileSync(join(templatesDir, 'v2', 'README.md.deleted'), '');
63
+ // v3: higher version of vite.config.ts (should be picked over v2 if targetVersion >= 3)
64
+ mkdirSync(join(templatesDir, 'v3'));
65
+ writeFileSync(join(templatesDir, 'v3', 'vite.config.ts.ejs'), 'export default { minify: false }');
66
+ const managedTemplates = [
67
+ 'package.json.ejs',
68
+ 'AGENTS.md.ejs',
69
+ '.project-config.json.ejs',
70
+ 'vite.config.ts.ejs',
71
+ 'README.md',
72
+ ];
73
+ const expectedV1 = [
74
+ {
75
+ relPath: 'package.json',
76
+ version: 1,
77
+ },
78
+ {
79
+ relPath: 'AGENTS.md',
80
+ version: 1,
81
+ },
82
+ {
83
+ relPath: '.project-config.json',
84
+ version: 1,
85
+ },
86
+ {
87
+ relPath: 'README.md',
88
+ version: 1,
89
+ },
90
+ ];
91
+ const resultV1 = collectManagedFiles(templatesDir, managedTemplates, 1);
92
+ expect(normalizeCollectedManagedFiles(resultV1)).toEqual(normalizeExpectedManagedFiles(expectedV1));
93
+ const expectedV2 = [
94
+ {
95
+ relPath: 'package.json',
96
+ version: 1,
97
+ },
98
+ {
99
+ relPath: 'AGENTS.md',
100
+ version: 1,
101
+ },
102
+ {
103
+ relPath: '.project-config.json',
104
+ version: 1,
105
+ },
106
+ {
107
+ relPath: 'vite.config.ts',
108
+ version: 2,
109
+ },
110
+ {
111
+ relPath: 'README.md',
112
+ version: 2,
113
+ deleted: true,
114
+ },
115
+ ];
116
+ const resultV2 = collectManagedFiles(templatesDir, managedTemplates, 2);
117
+ expect(normalizeCollectedManagedFiles(resultV2)).toEqual(normalizeExpectedManagedFiles(expectedV2));
118
+ const expectedV3 = [
119
+ {
120
+ relPath: 'package.json',
121
+ version: 1,
122
+ },
123
+ {
124
+ relPath: 'AGENTS.md',
125
+ version: 1,
126
+ },
127
+ {
128
+ relPath: '.project-config.json',
129
+ version: 1,
130
+ },
131
+ {
132
+ relPath: 'vite.config.ts',
133
+ version: 3,
134
+ },
135
+ {
136
+ relPath: 'README.md',
137
+ version: 2,
138
+ deleted: true,
139
+ },
140
+ ];
141
+ const resultV3 = collectManagedFiles(templatesDir, managedTemplates, 3);
142
+ expect(normalizeCollectedManagedFiles(resultV3)).toEqual(normalizeExpectedManagedFiles(expectedV3));
143
+ }
144
+ finally {
145
+ rmSync(templatesDir, { recursive: true, force: true });
146
+ }
147
+ });
148
+ });
149
+ describe('collectTemplateFiles', () => {
150
+ it('selects files from highest available version up to targetVersion and skips deleted', () => {
151
+ const templatesDir = mkdtempSync(join(tmpdir(), 'sce-collectTemplateFiles-'));
152
+ try {
153
+ mkdirSync(join(templatesDir, 'v1'));
154
+ writeFileSync(join(templatesDir, 'v1', 'package.json.ejs'), '{}');
155
+ writeFileSync(join(templatesDir, 'v1', 'AGENTS.md.ejs'), 'agents v1');
156
+ writeFileSync(join(templatesDir, 'v1', '.project-config.json.ejs'), '{}');
157
+ writeFileSync(join(templatesDir, 'v1', 'README.md.ejs'), 'readme v1');
158
+ mkdirSync(join(templatesDir, 'v2'));
159
+ writeFileSync(join(templatesDir, 'v2', 'vite.config.ts.ejs'), 'export default {}');
160
+ writeFileSync(join(templatesDir, 'v2', 'README.md.ejs.deleted'), '');
161
+ mkdirSync(join(templatesDir, 'v3'));
162
+ writeFileSync(join(templatesDir, 'v3', 'vite.config.ts.ejs'), 'export default { minify: false }');
163
+ const expectedV1 = [
164
+ {
165
+ relPath: '.project-config.json.ejs',
166
+ srcPath: join(templatesDir, 'v1', '.project-config.json.ejs'),
167
+ version: 1,
168
+ },
169
+ {
170
+ relPath: 'AGENTS.md.ejs',
171
+ srcPath: join(templatesDir, 'v1', 'AGENTS.md.ejs'),
172
+ version: 1,
173
+ },
174
+ {
175
+ relPath: 'README.md.ejs',
176
+ srcPath: join(templatesDir, 'v1', 'README.md.ejs'),
177
+ version: 1,
178
+ },
179
+ {
180
+ relPath: 'package.json.ejs',
181
+ srcPath: join(templatesDir, 'v1', 'package.json.ejs'),
182
+ version: 1,
183
+ },
184
+ ];
185
+ const resultV1 = collectTemplateFiles(templatesDir, 1);
186
+ expect(normalizeCollectedTemplateFiles(resultV1)).toEqual(normalizeExpectedTemplateFiles(expectedV1));
187
+ const expectedV2 = [
188
+ {
189
+ relPath: '.project-config.json.ejs',
190
+ srcPath: join(templatesDir, 'v1', '.project-config.json.ejs'),
191
+ version: 1,
192
+ },
193
+ {
194
+ relPath: 'AGENTS.md.ejs',
195
+ srcPath: join(templatesDir, 'v1', 'AGENTS.md.ejs'),
196
+ version: 1,
197
+ },
198
+ {
199
+ relPath: 'package.json.ejs',
200
+ srcPath: join(templatesDir, 'v1', 'package.json.ejs'),
201
+ version: 1,
202
+ },
203
+ {
204
+ relPath: 'vite.config.ts.ejs',
205
+ srcPath: join(templatesDir, 'v2', 'vite.config.ts.ejs'),
206
+ version: 2,
207
+ },
208
+ ];
209
+ const resultV2 = collectTemplateFiles(templatesDir, 2);
210
+ expect(normalizeCollectedTemplateFiles(resultV2)).toEqual(normalizeExpectedTemplateFiles(expectedV2));
211
+ const expectedV3 = [
212
+ {
213
+ relPath: '.project-config.json.ejs',
214
+ srcPath: join(templatesDir, 'v1', '.project-config.json.ejs'),
215
+ version: 1,
216
+ },
217
+ {
218
+ relPath: 'AGENTS.md.ejs',
219
+ srcPath: join(templatesDir, 'v1', 'AGENTS.md.ejs'),
220
+ version: 1,
221
+ },
222
+ {
223
+ relPath: 'package.json.ejs',
224
+ srcPath: join(templatesDir, 'v1', 'package.json.ejs'),
225
+ version: 1,
226
+ },
227
+ {
228
+ relPath: 'vite.config.ts.ejs',
229
+ srcPath: join(templatesDir, 'v3', 'vite.config.ts.ejs'),
230
+ version: 3,
231
+ },
232
+ ];
233
+ const resultV3 = collectTemplateFiles(templatesDir, 3);
234
+ expect(normalizeCollectedTemplateFiles(resultV3)).toEqual(normalizeExpectedTemplateFiles(expectedV3));
235
+ }
236
+ finally {
237
+ rmSync(templatesDir, { recursive: true, force: true });
238
+ }
239
+ });
240
+ it('collects template files from subDir with version overrides and delete markers', () => {
241
+ const templatesDir = mkdtempSync(join(tmpdir(), 'sce-collectTemplateFiles-subdir-'));
242
+ try {
243
+ mkdirSync(join(templatesDir, 'v1', 'public'), { recursive: true });
244
+ writeFileSync(join(templatesDir, 'v1', 'public', 'manifest.json.ejs'), '{"v":1}');
245
+ writeFileSync(join(templatesDir, 'v1', 'public', 'resolveSlotPage.js.ejs'), 'export default 1');
246
+ mkdirSync(join(templatesDir, 'v2', 'public'), { recursive: true });
247
+ writeFileSync(join(templatesDir, 'v2', 'public', 'manifest.json.ejs'), '{"v":2}');
248
+ writeFileSync(join(templatesDir, 'v2', 'public', 'resolveSlotPage.js.ejs.deleted'), '');
249
+ const result = collectTemplateFiles(templatesDir, 2, 'public');
250
+ const expected = [
251
+ {
252
+ relPath: 'manifest.json.ejs',
253
+ srcPath: join(templatesDir, 'v2', 'public', 'manifest.json.ejs'),
254
+ version: 2,
255
+ },
256
+ ];
257
+ expect(normalizeCollectedTemplateFiles(result)).toEqual(normalizeExpectedTemplateFiles(expected));
258
+ }
259
+ finally {
260
+ rmSync(templatesDir, { recursive: true, force: true });
261
+ }
262
+ });
263
+ });
@@ -0,0 +1,21 @@
1
+ import type { TNormalizedRelPath, TRelPath } from '../types.js';
2
+ export type TTemplateFile = {
3
+ deleted?: boolean;
4
+ relPath: TRelPath;
5
+ srcPath: string;
6
+ version: number;
7
+ };
8
+ export type TManagedFile = {
9
+ deleted?: boolean;
10
+ relPath: TRelPath;
11
+ version: number;
12
+ };
13
+ export type TNormalizedManagedFile = {
14
+ deleted?: boolean;
15
+ relPath: TNormalizedRelPath;
16
+ version: number;
17
+ };
18
+ export type TTemplateVersionDir = {
19
+ dirPath: string;
20
+ version: number;
21
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -1,9 +1,17 @@
1
- export type TCategory = 'games-and-fun' | 'sex-toys' | 'chat-bots' | 'broadcast-tools';
2
- export type TFramework = 'vanilla' | 'preact';
3
- export type TLanguage = 'ts' | 'js';
4
- export type TSlot = 'EXTENSION_SLOT_MAIN_GAME_FUN' | 'EXTENSION_SLOT_MAIN_SEX_TOY' | 'EXTENSION_SLOT_RIGHT_OVERLAY' | 'EXTENSION_SLOT_VIDEO_DECORATIVE_OVERLAY' | 'EXTENSION_SLOT_MOVEABLE_OVERLAY' | 'EXTENSION_SLOT_BACKGROUND';
5
- export type TPackageManager = 'npm' | 'yarn' | 'pnpm' | 'bun';
6
- export type TProjectConfig = {
1
+ import type { CATEGORIES, FRAMEWORKS, LANGUAGES, PACKAGE_MANAGERS, SLOTS } from './constants';
2
+ import type { TNormalizedManagedFile } from './templates/types';
3
+ export type TCategory = typeof CATEGORIES[number];
4
+ export type TRelPath = string;
5
+ export type TNormalizedRelPath = TRelPath & {
6
+ readonly __normalizedRelPath: true;
7
+ };
8
+ export type TFramework = typeof FRAMEWORKS[number];
9
+ export type TLanguage = typeof LANGUAGES[number];
10
+ export type TSlot = typeof SLOTS[number];
11
+ export type TPackageManager = typeof PACKAGE_MANAGERS[number];
12
+ export type TPackageDependenciesMap = Record<string, string>;
13
+ export type TCliCommandsMap = Record<string, string>;
14
+ export type TProjectConfigUserProps = {
7
15
  category: TCategory;
8
16
  framework: TFramework;
9
17
  language: TLanguage;
@@ -11,6 +19,14 @@ export type TProjectConfig = {
11
19
  packageManager: TPackageManager;
12
20
  slots: TSlot[];
13
21
  };
22
+ export type TProjectConfig = TProjectConfigUserProps & {
23
+ cliCommands: TCliCommandsMap;
24
+ dependencies: TPackageDependenciesMap;
25
+ devDependencies: TPackageDependenciesMap;
26
+ extHelperVersion: string;
27
+ lastTemplateVersion: number;
28
+ managedFiles: TNormalizedManagedFile[];
29
+ };
14
30
  export type TSlotEntry = {
15
31
  slot: TSlot;
16
32
  /** The camel cased version of the slot (e.g. `mainGameFun`). It's used as html file names */
@@ -20,12 +36,11 @@ export type TPackageManagerCommands = {
20
36
  build: string;
21
37
  dev: string;
22
38
  install: string;
39
+ templateUpdate: string;
23
40
  };
24
41
  export type TTemplateData = {
25
42
  config: TProjectConfig;
26
- entryModulePath?: string;
27
43
  ext: 'ts' | 'js';
28
- extHelperVersion: string;
29
44
  framework: TFramework;
30
45
  isJsxFramework: boolean;
31
46
  isTypescript: boolean;
@@ -34,8 +49,12 @@ export type TTemplateData = {
34
49
  name: string;
35
50
  packageManager: TPackageManager;
36
51
  packageManagerCommands: TPackageManagerCommands;
37
- slot?: string;
52
+ slots: TSlot[];
38
53
  slotsEntries: TSlotEntry[];
54
+ };
55
+ export type TTemplateSlotData = TTemplateData & {
56
+ entryModulePath?: string;
57
+ slot?: string;
39
58
  stylePath?: string;
40
59
  };
41
60
  export type TTemplateCommand = {
@@ -0,0 +1,2 @@
1
+ import type { TCategory } from '../types.js';
2
+ export declare const getIsValidCategory: (value: string) => value is TCategory;
@@ -0,0 +1,2 @@
1
+ import { CATEGORIES } from '../constants.js';
2
+ export const getIsValidCategory = (value) => CATEGORIES.includes(value);
@@ -0,0 +1 @@
1
+ export {};
@@ -1,10 +1,10 @@
1
1
  import { describe, expect, it } from 'vitest';
2
- import { isValidCategory } from './isValidCategory.js';
2
+ import { getIsValidCategory } from './getIsValidCategory.js';
3
3
  describe('isValidCategory', () => {
4
4
  it.each(['games-and-fun', 'sex-toys', 'chat-bots', 'broadcast-tools'])('returns true for valid category: %s', (cat) => {
5
- expect(isValidCategory(cat)).toBe(true);
5
+ expect(getIsValidCategory(cat)).toBe(true);
6
6
  });
7
7
  it.each(['invalid', '', 'Games-and-Fun', 'games_and_fun'])('returns false for invalid category: %s', (cat) => {
8
- expect(isValidCategory(cat)).toBe(false);
8
+ expect(getIsValidCategory(cat)).toBe(false);
9
9
  });
10
10
  });
@@ -0,0 +1,2 @@
1
+ import type { TFramework } from '../types.js';
2
+ export declare const getIsValidFramework: (value: string) => value is TFramework;
@@ -0,0 +1,2 @@
1
+ import { FRAMEWORKS } from '../constants.js';
2
+ export const getIsValidFramework = (value) => FRAMEWORKS.includes(value);
@@ -0,0 +1 @@
1
+ export {};
@@ -1,10 +1,10 @@
1
1
  import { describe, expect, it } from 'vitest';
2
- import { isValidFramework } from './isValidFramework.js';
2
+ import { getIsValidFramework } from './getIsValidFramework.js';
3
3
  describe('isValidFramework', () => {
4
4
  it.each(['vanilla', 'preact'])('returns true for valid framework: %s', (fw) => {
5
- expect(isValidFramework(fw)).toBe(true);
5
+ expect(getIsValidFramework(fw)).toBe(true);
6
6
  });
7
7
  it.each(['react', '', 'Vanilla', 'vue'])('returns false for invalid framework: %s', (fw) => {
8
- expect(isValidFramework(fw)).toBe(false);
8
+ expect(getIsValidFramework(fw)).toBe(false);
9
9
  });
10
10
  });