@unchainedshop/platform 4.8.11 → 5.0.0-alpha.2

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.
@@ -1,4 +1,4 @@
1
- import { FileDirector } from '@unchainedshop/file-upload';
1
+ import { FileDirector } from '@unchainedshop/core';
2
2
  export const setupUploadHandlers = ({ services, modules }) => {
3
3
  FileDirector.registerFileUploadCallback('user-avatars', async (file) => {
4
4
  return services.users.updateUserAvatarAfterUpload({ file });
@@ -1,5 +1,5 @@
1
1
  import { startAPIServer, roles } from '@unchainedshop/api';
2
- import { initCore } from '@unchainedshop/core';
2
+ import { initCore, pluginRegistry } from '@unchainedshop/core';
3
3
  import { initDb, mongodb, stopDb } from '@unchainedshop/mongodb';
4
4
  import { defaultLogger } from '@unchainedshop/logger';
5
5
  import { setupAccounts } from "./setup/setupAccounts.js";
@@ -37,15 +37,27 @@ export const startPlatform = async ({ modules, services, options, rolesOptions,
37
37
  const configuredRoles = roles.configureRoles(rolesOptions || {});
38
38
  const db = await initDb();
39
39
  const migrationRepository = createMigrationRepository(db);
40
+ const pluginModuleFactories = pluginRegistry.getModuleFactories();
41
+ const pluginModules = pluginModuleFactories.reduce((acc, factory) => {
42
+ const factoryModules = factory({ db });
43
+ Object.entries(factoryModules).forEach(([key, moduleInstance]) => {
44
+ acc[key] = {
45
+ configure: () => moduleInstance,
46
+ };
47
+ });
48
+ return acc;
49
+ }, {});
50
+ const allModules = { ...pluginModules, ...(modules || {}) };
40
51
  const unchainedAPI = await initCore({
41
52
  db,
42
53
  migrationRepository,
43
54
  bulkImporter,
44
- modules,
55
+ modules: allModules,
45
56
  services,
46
57
  options,
47
58
  bulkExporter,
48
59
  });
60
+ await pluginRegistry.initialize(unchainedAPI);
49
61
  setupAccounts(unchainedAPI);
50
62
  setupTemplates(unchainedAPI);
51
63
  setupUploadHandlers(unchainedAPI);
@@ -77,6 +89,8 @@ export const startPlatform = async ({ modules, services, options, rolesOptions,
77
89
  try {
78
90
  defaultLogger.debug('Stopping Workqueue', { signal });
79
91
  stopWorkqueue();
92
+ defaultLogger.debug('Shutting down plugins', { signal });
93
+ await pluginRegistry.shutdown(unchainedAPI);
80
94
  defaultLogger.debug('Stopping GraphQL server', { signal });
81
95
  await graphqlHandler.dispose();
82
96
  defaultLogger.debug('Stopping DB Connection', { signal });
package/package.json CHANGED
@@ -1,13 +1,10 @@
1
1
  {
2
2
  "name": "@unchainedshop/platform",
3
3
  "description": "Complete e-commerce platform bundle for the Unchained Engine",
4
- "version": "4.8.11",
4
+ "version": "5.0.0-alpha.2",
5
5
  "main": "lib/platform-index.js",
6
6
  "types": "lib/platform-index.d.ts",
7
7
  "type": "module",
8
- "bin": {
9
- "unchained": "./bin/unchained.js"
10
- },
11
8
  "scripts": {
12
9
  "clean": "tsc -b --clean",
13
10
  "build": "tsc -b",
@@ -41,15 +38,14 @@
41
38
  "npm": ">=10.0.0"
42
39
  },
43
40
  "dependencies": {
44
- "@unchainedshop/api": "^4.6.0",
45
- "@unchainedshop/core": "^4.6.0",
46
- "@unchainedshop/events": "^4.6.0",
47
- "@unchainedshop/file-upload": "^4.6.0",
48
- "@unchainedshop/logger": "^4.6.0",
49
- "@unchainedshop/mongodb": "^4.6.0",
50
- "@unchainedshop/plugins": "^4.6.0",
51
- "@unchainedshop/roles": "^4.6.0",
52
- "@unchainedshop/utils": "^4.6.0",
41
+ "@unchainedshop/api": "^5.0.0-alpha.1",
42
+ "@unchainedshop/core": "^5.0.0-alpha.1",
43
+ "@unchainedshop/events": "^5.0.0-alpha.1",
44
+ "@unchainedshop/logger": "^5.0.0-alpha.1",
45
+ "@unchainedshop/mongodb": "^5.0.0-alpha.1",
46
+ "@unchainedshop/plugins": "^5.0.0-alpha.1",
47
+ "@unchainedshop/roles": "^5.0.0-alpha.1",
48
+ "@unchainedshop/utils": "^5.0.0-alpha.1",
53
49
  "safe-stable-stringify": "^2.5.0"
54
50
  },
55
51
  "devDependencies": {
package/bin/unchained.js DELETED
@@ -1,161 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import { execFileSync } from 'node:child_process';
4
- import {
5
- cpSync,
6
- existsSync,
7
- mkdtempSync,
8
- readFileSync,
9
- readdirSync,
10
- rmSync,
11
- writeFileSync,
12
- } from 'node:fs';
13
- import { join, relative } from 'node:path';
14
- import { tmpdir } from 'node:os';
15
- import { createRequire } from 'node:module';
16
-
17
- const GITHUB_REPO = 'https://github.com/unchainedshop/unchained.git';
18
- const DOCS_SUBPATH = 'docs/docs';
19
- const DOCS_DIR = join(process.cwd(), '.unchained-docs');
20
- const INDEX_START = '<!-- UNCHAINED_DOCS_INDEX:BEGIN -->';
21
- const INDEX_END = '<!-- UNCHAINED_DOCS_INDEX:END -->';
22
-
23
- const command = process.argv[2];
24
-
25
- if (command !== 'download-llm-docs') {
26
- console.log(`Usage: unchained <command>
27
-
28
- Commands:
29
- download-llm-docs Download Unchained Engine docs for LLM coding assistants
30
- (Claude Code, Cursor, etc.) and inject a file index into
31
- CLAUDE.md and/or agents.md`);
32
- process.exit(command ? 1 : 0);
33
- }
34
-
35
- // Resolve version from own package.json
36
- const require = createRequire(import.meta.url);
37
- const pkg = require('../package.json');
38
- const version = pkg.version;
39
-
40
- // Determine git ref: try tag first, fallback to master
41
- function tagExists(tag) {
42
- try {
43
- execFileSync('git', ['ls-remote', '--tags', '--exit-code', GITHUB_REPO, `refs/tags/${tag}`], {
44
- stdio: 'pipe',
45
- });
46
- return true;
47
- } catch {
48
- return false;
49
- }
50
- }
51
-
52
- const tag = `v${version}`;
53
- const ref = tagExists(tag) ? tag : 'master';
54
- if (ref === 'master') {
55
- console.log(`Tag ${tag} not found on remote, falling back to master branch.`);
56
- }
57
-
58
- // Clone docs using sparse-checkout into a temp directory
59
- const tempDir = mkdtempSync(join(tmpdir(), 'unchained-docs-'));
60
- console.log(`Cloning docs from ${ref} using sparse-checkout ...`);
61
- try {
62
- execFileSync(
63
- 'git',
64
- [
65
- 'clone',
66
- '--filter=blob:none',
67
- '--no-checkout',
68
- '--depth',
69
- '1',
70
- '--branch',
71
- ref,
72
- GITHUB_REPO,
73
- tempDir,
74
- ],
75
- { stdio: 'inherit' },
76
- );
77
- execFileSync('git', ['-C', tempDir, 'sparse-checkout', 'set', DOCS_SUBPATH], {
78
- stdio: 'inherit',
79
- });
80
- execFileSync('git', ['-C', tempDir, 'checkout'], { stdio: 'inherit' });
81
- } catch {
82
- rmSync(tempDir, { recursive: true, force: true });
83
- console.error('Failed to clone docs repository.');
84
- process.exit(1);
85
- }
86
-
87
- // Copy docs/docs/ contents to .unchained-docs/
88
- const sourceDir = join(tempDir, DOCS_SUBPATH);
89
- if (!existsSync(sourceDir)) {
90
- rmSync(tempDir, { recursive: true, force: true });
91
- console.error(`Docs directory not found at ${DOCS_SUBPATH} in the repository.`);
92
- process.exit(1);
93
- }
94
-
95
- rmSync(DOCS_DIR, { recursive: true, force: true });
96
- cpSync(sourceDir, DOCS_DIR, { recursive: true });
97
- rmSync(tempDir, { recursive: true, force: true });
98
-
99
- // Scan for markdown files
100
- const markdownsByDir = Map.groupBy(
101
- readdirSync(DOCS_DIR, { withFileTypes: true, recursive: true }).filter(
102
- (e) => e.isFile() && (e.name.endsWith('.md') || e.name.endsWith('.mdx')),
103
- ),
104
- (e) => relative(DOCS_DIR, e.parentPath) || '.',
105
- );
106
-
107
- const fileCount = [...markdownsByDir.values()].flat().length;
108
- console.log(`Found ${fileCount} markdown files in .unchained-docs/`);
109
-
110
- // Build compact pipe-delimited index
111
- const indexSnippet = [
112
- INDEX_START,
113
- [
114
- `[Unchained Engine v${version} Docs Index]`,
115
- 'root: ./.unchained-docs',
116
- 'Search these docs before answering Unchained questions.',
117
- 'If docs missing, run: npx unchained download-llm-docs',
118
- ...[...markdownsByDir]
119
- .sort(([a], [b]) => a.localeCompare(b))
120
- .map(
121
- ([dir, entries]) =>
122
- `${dir}:{${entries
123
- .map((e) => e.name)
124
- .sort()
125
- .join(',')}}`,
126
- ),
127
- ].join('|'),
128
- INDEX_END,
129
- ].join('');
130
-
131
- // Upsert index into target files
132
- function upsertIndex(filePath) {
133
- const content = readFileSync(filePath, 'utf-8');
134
- const [before, ...afterParts] = content.split(INDEX_START);
135
- const after =
136
- afterParts.length > 0
137
- ? afterParts.join(INDEX_START).split(INDEX_END).slice(1).join(INDEX_END)
138
- : undefined;
139
-
140
- writeFileSync(
141
- filePath,
142
- after !== undefined ? before + indexSnippet + after : `${content.trimEnd()}\n${indexSnippet}\n`,
143
- );
144
- console.log(`Updated ${relative(process.cwd(), filePath)} with docs index.`);
145
- }
146
-
147
- const claudeMdPath = join(process.cwd(), 'CLAUDE.md');
148
- const agentsMdPath = join(process.cwd(), 'agents.md');
149
- const claudeExists = existsSync(claudeMdPath);
150
- const agentsExists = existsSync(agentsMdPath);
151
-
152
- if (claudeExists) upsertIndex(claudeMdPath);
153
- if (agentsExists) upsertIndex(agentsMdPath);
154
-
155
- if (!claudeExists && !agentsExists) {
156
- writeFileSync(claudeMdPath, `${indexSnippet}\n`);
157
- console.log('Created CLAUDE.md with docs index.');
158
- }
159
-
160
- // Remind about .gitignore
161
- console.log('\nDone! Remember to add .unchained-docs to your .gitignore.');