@jskit-ai/create-app 0.1.2 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/jskit-create-app.js +2 -2
- package/package.json +7 -5
- package/src/client/index.js +1 -0
- package/src/index.js +1 -0
- package/src/{shared → server}/index.js +56 -61
- package/templates/base-shell/.jskit/lock.json +31 -0
- package/templates/base-shell/README.md +24 -20
- package/templates/base-shell/app.scripts.config.mjs +1 -1
- package/templates/base-shell/config/public.js +30 -0
- package/templates/base-shell/config/server.js +1 -0
- package/templates/base-shell/config/surfaceAccessPolicies.js +12 -0
- package/templates/base-shell/eslint.config.mjs +1 -1
- package/templates/base-shell/gitignore +2 -0
- package/templates/base-shell/index.html +1 -1
- package/templates/base-shell/jsconfig.json +8 -0
- package/templates/base-shell/package.json +43 -18
- package/templates/base-shell/packages/main/package.descriptor.mjs +55 -0
- package/templates/base-shell/packages/main/package.json +12 -0
- package/templates/base-shell/packages/main/src/client/index.js +13 -0
- package/templates/base-shell/packages/main/src/client/providers/MainClientProvider.js +33 -0
- package/templates/base-shell/packages/main/src/server/controllers/index.js +9 -0
- package/templates/base-shell/packages/main/src/server/index.js +1 -0
- package/templates/base-shell/packages/main/src/server/providers/MainServiceProvider.js +22 -0
- package/templates/base-shell/packages/main/src/server/routes/index.js +9 -0
- package/templates/base-shell/packages/main/src/server/services/index.js +9 -0
- package/templates/base-shell/packages/main/src/server/support/loadAppConfig.js +55 -0
- package/templates/base-shell/packages/main/src/shared/index.js +8 -0
- package/templates/base-shell/packages/main/src/shared/schemas/index.js +20 -0
- package/templates/base-shell/scripts/dev-bootstrap-jskit.sh +110 -0
- package/templates/base-shell/scripts/just_run_verde +37 -0
- package/templates/base-shell/scripts/link-local-jskit-packages.sh +90 -0
- package/templates/base-shell/scripts/update-jskit-packages.sh +73 -0
- package/templates/base-shell/scripts/verdaccio/config.yaml +26 -0
- package/templates/base-shell/scripts/verdaccio-reset-and-publish-packages.sh +314 -0
- package/templates/base-shell/server/lib/runtimeEnv.js +29 -0
- package/templates/base-shell/server/lib/surfaceRuntime.js +10 -0
- package/templates/base-shell/server.js +39 -68
- package/templates/base-shell/src/App.vue +11 -22
- package/templates/base-shell/src/main.js +87 -1
- package/templates/base-shell/src/pages/console/index.vue +12 -0
- package/templates/base-shell/src/pages/console.vue +13 -0
- package/templates/base-shell/src/pages/home/index.vue +12 -0
- package/templates/base-shell/src/pages/home.vue +13 -0
- package/templates/base-shell/src/views/NotFound.vue +13 -0
- package/templates/base-shell/tests/server/{minimalShell.contract.test.js → minimalShell.validator.test.js} +44 -6
- package/templates/base-shell/tests/server/smoke.test.js +3 -6
- package/templates/base-shell/vite.config.mjs +24 -3
- package/templates/base-shell/vite.shared.mjs +51 -1
- package/README.md +0 -24
- package/templates/base-shell/package.json.ACTUAL_CORRECT +0 -38
- /package/src/{shared → server}/cliEntrypoint.js +0 -0
package/bin/jskit-create-app.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { runCliEntrypoint } from "../src/
|
|
3
|
-
import { runCli } from "../src/
|
|
2
|
+
import { runCliEntrypoint } from "../src/server/cliEntrypoint.js";
|
|
3
|
+
import { runCli } from "../src/server/index.js";
|
|
4
4
|
|
|
5
5
|
await runCliEntrypoint(runCli);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jskit-ai/create-app",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "Scaffold minimal JSKIT app shells.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -10,13 +10,15 @@
|
|
|
10
10
|
"README.md"
|
|
11
11
|
],
|
|
12
12
|
"scripts": {
|
|
13
|
-
"test": "node --test"
|
|
13
|
+
"test": "node --test test/*.test.js"
|
|
14
14
|
},
|
|
15
15
|
"bin": {
|
|
16
16
|
"jskit-create-app": "bin/jskit-create-app.js"
|
|
17
17
|
},
|
|
18
18
|
"exports": {
|
|
19
|
-
".": "./src/
|
|
19
|
+
".": "./src/index.js",
|
|
20
|
+
"./server": "./src/server/index.js",
|
|
21
|
+
"./client": "./src/client/index.js"
|
|
20
22
|
},
|
|
21
23
|
"dependencies": {},
|
|
22
24
|
"engines": {
|
|
@@ -28,12 +30,12 @@
|
|
|
28
30
|
"repository": {
|
|
29
31
|
"type": "git",
|
|
30
32
|
"url": "git+https://github.com/mobily-enterprises/jskit-ai.git",
|
|
31
|
-
"directory": "
|
|
33
|
+
"directory": "tooling/create-app"
|
|
32
34
|
},
|
|
33
35
|
"bugs": {
|
|
34
36
|
"url": "https://github.com/mobily-enterprises/jskit-ai/issues"
|
|
35
37
|
},
|
|
36
|
-
"homepage": "https://github.com/mobily-enterprises/jskit-ai/tree/main/
|
|
38
|
+
"homepage": "https://github.com/mobily-enterprises/jskit-ai/tree/main/tooling/create-app#readme",
|
|
37
39
|
"keywords": [
|
|
38
40
|
"jskit",
|
|
39
41
|
"scaffold",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/src/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
throw new Error("Use explicit entrypoint import for @jskit-ai/create-app: /server or /client.");
|
|
@@ -7,9 +7,8 @@ import { shellQuote } from "./cliEntrypoint.js";
|
|
|
7
7
|
|
|
8
8
|
const DEFAULT_TEMPLATE = "base-shell";
|
|
9
9
|
const DEFAULT_INITIAL_BUNDLES = "none";
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
const DB_PROVIDERS = new Set(["mysql", "postgres"]);
|
|
10
|
+
const INITIAL_BUNDLE_PRESETS = new Set(["none", "auth"]);
|
|
11
|
+
const TENANCY_MODES = new Set(["none", "personal", "workspace"]);
|
|
13
12
|
const ALLOWED_EXISTING_TARGET_ENTRIES = new Set([".git"]);
|
|
14
13
|
const PACKAGE_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../..");
|
|
15
14
|
const TEMPLATES_ROOT = path.join(PACKAGE_ROOT, "templates");
|
|
@@ -38,46 +37,34 @@ function normalizeInitialBundlesPreset(value, { showUsage = true } = {}) {
|
|
|
38
37
|
}
|
|
39
38
|
|
|
40
39
|
throw createCliError(
|
|
41
|
-
`Invalid --initial-bundles value "${value}". Expected one of: none,
|
|
40
|
+
`Invalid --initial-bundles value "${value}". Expected one of: none, auth.`,
|
|
42
41
|
{ showUsage }
|
|
43
42
|
);
|
|
44
43
|
}
|
|
45
44
|
|
|
46
|
-
function
|
|
47
|
-
const normalized = String(value ||
|
|
48
|
-
if (
|
|
45
|
+
function normalizeTenancyMode(value, { showUsage = true } = {}) {
|
|
46
|
+
const normalized = String(value || "").trim().toLowerCase();
|
|
47
|
+
if (TENANCY_MODES.has(normalized)) {
|
|
49
48
|
return normalized;
|
|
50
49
|
}
|
|
51
50
|
|
|
52
51
|
throw createCliError(
|
|
53
|
-
`Invalid --
|
|
52
|
+
`Invalid --tenancy-mode value "${value}". Expected one of: none, personal, workspace.`,
|
|
54
53
|
{ showUsage }
|
|
55
54
|
);
|
|
56
55
|
}
|
|
57
56
|
|
|
58
|
-
function buildInitialBundleCommands(initialBundles
|
|
57
|
+
function buildInitialBundleCommands(initialBundles) {
|
|
59
58
|
const normalizedPreset = normalizeInitialBundlesPreset(initialBundles, { showUsage: false });
|
|
60
|
-
const normalizedProvider = normalizeDbProvider(dbProvider, { showUsage: false });
|
|
61
59
|
|
|
62
60
|
const commands = [];
|
|
63
|
-
if (normalizedPreset === "
|
|
64
|
-
commands.push(`npx jskit add db --provider ${normalizedProvider} --no-install`);
|
|
65
|
-
}
|
|
66
|
-
if (normalizedPreset === "db-auth") {
|
|
61
|
+
if (normalizedPreset === "auth") {
|
|
67
62
|
commands.push("npx jskit add auth-base --no-install");
|
|
68
63
|
}
|
|
69
64
|
|
|
70
65
|
return commands;
|
|
71
66
|
}
|
|
72
67
|
|
|
73
|
-
function buildProgressiveBundleCommands(dbProvider) {
|
|
74
|
-
const normalizedProvider = normalizeDbProvider(dbProvider, { showUsage: false });
|
|
75
|
-
return [
|
|
76
|
-
`npx jskit add db --provider ${normalizedProvider} --no-install`,
|
|
77
|
-
"npx jskit add auth-base --no-install"
|
|
78
|
-
];
|
|
79
|
-
}
|
|
80
|
-
|
|
81
68
|
function validateAppName(appName, { showUsage = true } = {}) {
|
|
82
69
|
if (!appName || typeof appName !== "string") {
|
|
83
70
|
throw createCliError("Missing app name.", { showUsage });
|
|
@@ -112,7 +99,7 @@ function parseCliArgs(argv) {
|
|
|
112
99
|
template: DEFAULT_TEMPLATE,
|
|
113
100
|
target: null,
|
|
114
101
|
initialBundles: DEFAULT_INITIAL_BUNDLES,
|
|
115
|
-
|
|
102
|
+
tenancyMode: null,
|
|
116
103
|
force: false,
|
|
117
104
|
dryRun: false,
|
|
118
105
|
help: false,
|
|
@@ -192,15 +179,15 @@ function parseCliArgs(argv) {
|
|
|
192
179
|
continue;
|
|
193
180
|
}
|
|
194
181
|
|
|
195
|
-
if (arg === "--
|
|
196
|
-
const { value, nextIndex } = parseOptionWithValue(args, index, "--
|
|
197
|
-
options.
|
|
182
|
+
if (arg === "--tenancy-mode") {
|
|
183
|
+
const { value, nextIndex } = parseOptionWithValue(args, index, "--tenancy-mode");
|
|
184
|
+
options.tenancyMode = value;
|
|
198
185
|
index = nextIndex;
|
|
199
186
|
continue;
|
|
200
187
|
}
|
|
201
188
|
|
|
202
|
-
if (arg.startsWith("--
|
|
203
|
-
options.
|
|
189
|
+
if (arg.startsWith("--tenancy-mode=")) {
|
|
190
|
+
options.tenancyMode = arg.slice("--tenancy-mode=".length);
|
|
204
191
|
continue;
|
|
205
192
|
}
|
|
206
193
|
|
|
@@ -239,8 +226,8 @@ function printUsage(stream = process.stderr) {
|
|
|
239
226
|
stream.write(` --template <name> Template folder under templates/ (default: ${DEFAULT_TEMPLATE})\n`);
|
|
240
227
|
stream.write(" --title <text> App title used for template replacements\n");
|
|
241
228
|
stream.write(" --target <path> Target directory (default: ./<app-name>)\n");
|
|
242
|
-
stream.write(" --initial-bundles <preset> Optional bundle preset: none |
|
|
243
|
-
stream.write(" --
|
|
229
|
+
stream.write(" --initial-bundles <preset> Optional bundle preset: none | auth (default: none)\n");
|
|
230
|
+
stream.write(" --tenancy-mode <mode> Optional config seed: none | personal | workspace\n");
|
|
244
231
|
stream.write(" --force Allow writing into a non-empty target directory\n");
|
|
245
232
|
stream.write(" --dry-run Print planned writes without changing the filesystem\n");
|
|
246
233
|
stream.write(" --interactive Prompt for app values instead of passing all flags\n");
|
|
@@ -255,15 +242,35 @@ function applyPlaceholders(source, replacements) {
|
|
|
255
242
|
return output;
|
|
256
243
|
}
|
|
257
244
|
|
|
258
|
-
|
|
259
|
-
const
|
|
260
|
-
|
|
245
|
+
function isPathWithinRoot(rootPath, candidatePath) {
|
|
246
|
+
const relativePath = path.relative(rootPath, candidatePath);
|
|
247
|
+
return relativePath === "" || (!relativePath.startsWith("..") && !path.isAbsolute(relativePath));
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
function normalizeTemplatePathSegments(templateName) {
|
|
251
|
+
const rawTemplateName = String(templateName || "").trim();
|
|
252
|
+
if (!rawTemplateName) {
|
|
261
253
|
throw createCliError("Template name cannot be empty.", {
|
|
262
254
|
showUsage: true
|
|
263
255
|
});
|
|
264
256
|
}
|
|
265
257
|
|
|
266
|
-
const
|
|
258
|
+
const segments = rawTemplateName.split(/[\\/]+/).filter(Boolean);
|
|
259
|
+
if (segments.length < 1 || segments.some((segment) => segment === "." || segment === "..")) {
|
|
260
|
+
throw createCliError(`Invalid template "${rawTemplateName}".`);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
return segments;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
async function resolveTemplateDirectory(templateName) {
|
|
267
|
+
const templatePathSegments = normalizeTemplatePathSegments(templateName);
|
|
268
|
+
const cleanTemplate = templatePathSegments.join(path.sep);
|
|
269
|
+
const templateDir = path.resolve(TEMPLATES_ROOT, ...templatePathSegments);
|
|
270
|
+
|
|
271
|
+
if (!isPathWithinRoot(TEMPLATES_ROOT, templateDir)) {
|
|
272
|
+
throw createCliError(`Invalid template "${cleanTemplate}".`);
|
|
273
|
+
}
|
|
267
274
|
|
|
268
275
|
try {
|
|
269
276
|
const templateStats = await stat(templateDir);
|
|
@@ -456,7 +463,7 @@ async function collectInteractiveOptions({
|
|
|
456
463
|
while (true) {
|
|
457
464
|
const candidate = await askQuestion(
|
|
458
465
|
readline,
|
|
459
|
-
"Initial bundle preset (none|
|
|
466
|
+
"Initial bundle preset (none|auth)",
|
|
460
467
|
initialBundles
|
|
461
468
|
);
|
|
462
469
|
try {
|
|
@@ -467,27 +474,13 @@ async function collectInteractiveOptions({
|
|
|
467
474
|
}
|
|
468
475
|
}
|
|
469
476
|
|
|
470
|
-
let dbProvider = normalizeDbProvider(parsed.dbProvider, { showUsage: false });
|
|
471
|
-
if (initialBundles === "db" || initialBundles === "db-auth") {
|
|
472
|
-
while (true) {
|
|
473
|
-
const candidate = await askQuestion(readline, "DB provider (mysql|postgres)", dbProvider);
|
|
474
|
-
try {
|
|
475
|
-
dbProvider = normalizeDbProvider(candidate, { showUsage: false });
|
|
476
|
-
break;
|
|
477
|
-
} catch (error) {
|
|
478
|
-
stderr.write(`Error: ${error?.message || String(error)}\n`);
|
|
479
|
-
}
|
|
480
|
-
}
|
|
481
|
-
}
|
|
482
|
-
|
|
483
477
|
return {
|
|
484
478
|
appName,
|
|
485
479
|
appTitle,
|
|
486
480
|
target,
|
|
487
481
|
template,
|
|
488
482
|
force,
|
|
489
|
-
initialBundles
|
|
490
|
-
dbProvider
|
|
483
|
+
initialBundles
|
|
491
484
|
};
|
|
492
485
|
} finally {
|
|
493
486
|
readline.close();
|
|
@@ -500,7 +493,7 @@ export async function createApp({
|
|
|
500
493
|
template = DEFAULT_TEMPLATE,
|
|
501
494
|
target = null,
|
|
502
495
|
initialBundles = DEFAULT_INITIAL_BUNDLES,
|
|
503
|
-
|
|
496
|
+
tenancyMode = null,
|
|
504
497
|
force = false,
|
|
505
498
|
dryRun = false,
|
|
506
499
|
cwd = process.cwd()
|
|
@@ -510,7 +503,10 @@ export async function createApp({
|
|
|
510
503
|
|
|
511
504
|
const resolvedAppTitle = String(appTitle || "").trim() || toAppTitle(resolvedAppName);
|
|
512
505
|
const resolvedInitialBundles = normalizeInitialBundlesPreset(initialBundles);
|
|
513
|
-
const
|
|
506
|
+
const resolvedTenancyMode =
|
|
507
|
+
tenancyMode == null || String(tenancyMode).trim() === ""
|
|
508
|
+
? null
|
|
509
|
+
: normalizeTenancyMode(tenancyMode);
|
|
514
510
|
|
|
515
511
|
const resolvedCwd = path.resolve(cwd);
|
|
516
512
|
const targetDirectory = path.resolve(resolvedCwd, target ? String(target) : resolvedAppName);
|
|
@@ -523,7 +519,10 @@ export async function createApp({
|
|
|
523
519
|
|
|
524
520
|
const replacements = {
|
|
525
521
|
__APP_NAME__: resolvedAppName,
|
|
526
|
-
__APP_TITLE__: resolvedAppTitle
|
|
522
|
+
__APP_TITLE__: resolvedAppTitle,
|
|
523
|
+
__TENANCY_MODE_LINE__: resolvedTenancyMode
|
|
524
|
+
? `config.tenancyMode = "${resolvedTenancyMode}";\n`
|
|
525
|
+
: ""
|
|
527
526
|
};
|
|
528
527
|
|
|
529
528
|
const touchedFiles = await copyTemplateDirectory({
|
|
@@ -538,9 +537,8 @@ export async function createApp({
|
|
|
538
537
|
appTitle: resolvedAppTitle,
|
|
539
538
|
template: String(template),
|
|
540
539
|
initialBundles: resolvedInitialBundles,
|
|
541
|
-
|
|
542
|
-
selectedBundleCommands: buildInitialBundleCommands(resolvedInitialBundles
|
|
543
|
-
progressiveBundleCommands: buildProgressiveBundleCommands(resolvedDbProvider),
|
|
540
|
+
tenancyMode: resolvedTenancyMode,
|
|
541
|
+
selectedBundleCommands: buildInitialBundleCommands(resolvedInitialBundles),
|
|
544
542
|
targetDirectory,
|
|
545
543
|
dryRun,
|
|
546
544
|
touchedFiles
|
|
@@ -584,7 +582,7 @@ export async function runCli(
|
|
|
584
582
|
template: resolvedOptions.template,
|
|
585
583
|
target: resolvedOptions.target,
|
|
586
584
|
initialBundles: resolvedOptions.initialBundles,
|
|
587
|
-
|
|
585
|
+
tenancyMode: resolvedOptions.tenancyMode,
|
|
588
586
|
force: resolvedOptions.force,
|
|
589
587
|
dryRun: resolvedOptions.dryRun,
|
|
590
588
|
cwd
|
|
@@ -598,7 +596,6 @@ export async function runCli(
|
|
|
598
596
|
} else {
|
|
599
597
|
stdout.write(`Created app "${result.appName}" from template "${result.template}" at ${targetLabel}.\n`);
|
|
600
598
|
}
|
|
601
|
-
|
|
602
599
|
stdout.write(`${result.dryRun ? "Planned" : "Written"} files (${result.touchedFiles.length}):\n`);
|
|
603
600
|
for (const filePath of result.touchedFiles) {
|
|
604
601
|
stdout.write(`- ${filePath}\n`);
|
|
@@ -619,9 +616,7 @@ export async function runCli(
|
|
|
619
616
|
}
|
|
620
617
|
} else {
|
|
621
618
|
stdout.write("Add framework capabilities when ready:\n");
|
|
622
|
-
|
|
623
|
-
stdout.write(`- ${command}\n`);
|
|
624
|
-
}
|
|
619
|
+
stdout.write("- npx jskit add auth-base --no-install\n");
|
|
625
620
|
}
|
|
626
621
|
}
|
|
627
622
|
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"lockVersion": 1,
|
|
3
|
+
"installedPackages": {
|
|
4
|
+
"@local/main": {
|
|
5
|
+
"packageId": "@local/main",
|
|
6
|
+
"version": "0.1.0",
|
|
7
|
+
"source": {
|
|
8
|
+
"type": "local-package",
|
|
9
|
+
"packagePath": "packages/main",
|
|
10
|
+
"descriptorPath": "packages/main/package.descriptor.mjs"
|
|
11
|
+
},
|
|
12
|
+
"managed": {
|
|
13
|
+
"packageJson": {
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"@local/main": {
|
|
16
|
+
"hadPrevious": false,
|
|
17
|
+
"previousValue": "",
|
|
18
|
+
"value": "file:packages/main"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {},
|
|
22
|
+
"scripts": {}
|
|
23
|
+
},
|
|
24
|
+
"text": {},
|
|
25
|
+
"files": []
|
|
26
|
+
},
|
|
27
|
+
"options": {},
|
|
28
|
+
"installedAt": "1970-01-01T00:00:00.000Z"
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -1,39 +1,43 @@
|
|
|
1
1
|
# __APP_TITLE__
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Generated with `jskit-create-app` (template: `base-shell`).
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Quickstart
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
```bash
|
|
8
|
+
npm install
|
|
9
|
+
npm run dev
|
|
10
|
+
```
|
|
8
11
|
|
|
9
|
-
|
|
10
|
-
- tiny Vue client shell
|
|
11
|
-
- standardized scripts via `@jskit-ai/app-scripts`
|
|
12
|
+
## Package Bootstrap
|
|
12
13
|
|
|
13
|
-
|
|
14
|
+
`npm install` runs `scripts/dev-bootstrap-jskit.sh` through `preinstall`.
|
|
14
15
|
|
|
15
|
-
|
|
16
|
+
- Default mode is `JSKIT_DEV_BOOTSTRAP=auto`.
|
|
17
|
+
- In Dokku (`DOKKU_APP_NAME`/`DOKKU_APP_TYPE` detected), auto mode runs bootstrap.
|
|
18
|
+
- Outside Dokku, auto mode skips bootstrap (local dev stays quiet).
|
|
16
19
|
|
|
17
|
-
|
|
18
|
-
- auth/workspace modules
|
|
19
|
-
- billing/chat/social/ai modules
|
|
20
|
-
- app-local framework composition engines
|
|
20
|
+
Set `JSKIT_GITHUB_TARBALL_URL` in Dokku when local JSKIT packages are not published to npm yet.
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
Refresh JSKIT dependencies to the latest published versions:
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
```bash
|
|
25
|
+
npm run jskit:update
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Server
|
|
25
29
|
|
|
26
30
|
```bash
|
|
27
|
-
npm install
|
|
28
|
-
npm run dev
|
|
29
31
|
npm run server
|
|
30
|
-
npm run test
|
|
31
|
-
npm run test:client
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
App configuration files:
|
|
35
|
+
|
|
36
|
+
- `config/public.js` for client-visible feature toggles, including surface definitions.
|
|
37
|
+
- `config/server.js` for server-only toggles/secrets wiring.
|
|
38
|
+
|
|
39
|
+
## Add Capabilities
|
|
35
40
|
|
|
36
41
|
```bash
|
|
37
|
-
npx jskit add db --provider mysql --no-install
|
|
38
42
|
npx jskit add auth-base --no-install
|
|
39
43
|
```
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { surfaceAccessPolicies } from "./surfaceAccessPolicies.js";
|
|
2
|
+
|
|
3
|
+
export const config = {};
|
|
4
|
+
__TENANCY_MODE_LINE__
|
|
5
|
+
|
|
6
|
+
config.surfaceModeAll = "all";
|
|
7
|
+
config.surfaceDefaultId = "home";
|
|
8
|
+
config.webRootAllowed = "no";
|
|
9
|
+
config.surfaceAccessPolicies = surfaceAccessPolicies;
|
|
10
|
+
config.surfaceDefinitions = {};
|
|
11
|
+
config.surfaceDefinitions.home = {
|
|
12
|
+
id: "home",
|
|
13
|
+
label: "Home",
|
|
14
|
+
pagesRoot: "home",
|
|
15
|
+
enabled: true,
|
|
16
|
+
requiresAuth: false,
|
|
17
|
+
requiresWorkspace: false,
|
|
18
|
+
accessPolicyId: "public",
|
|
19
|
+
origin: ""
|
|
20
|
+
};
|
|
21
|
+
config.surfaceDefinitions.console = {
|
|
22
|
+
id: "console",
|
|
23
|
+
label: "Console",
|
|
24
|
+
pagesRoot: "console",
|
|
25
|
+
enabled: true,
|
|
26
|
+
requiresAuth: true,
|
|
27
|
+
requiresWorkspace: false,
|
|
28
|
+
accessPolicyId: "console_owner",
|
|
29
|
+
origin: ""
|
|
30
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const config = {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export const surfaceAccessPolicies = {};
|
|
2
|
+
|
|
3
|
+
surfaceAccessPolicies.public = {};
|
|
4
|
+
|
|
5
|
+
surfaceAccessPolicies.authenticated = {
|
|
6
|
+
requireAuth: true
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
surfaceAccessPolicies.console_owner = {
|
|
10
|
+
requireAuth: true,
|
|
11
|
+
requireFlagsAll: ["console_owner"]
|
|
12
|
+
};
|
|
@@ -7,32 +7,57 @@
|
|
|
7
7
|
"engines": {
|
|
8
8
|
"node": "20.x"
|
|
9
9
|
},
|
|
10
|
-
"bin": {
|
|
11
|
-
"jskit": "node_modules/@jskit-ai/jskit/packages/tooling/jskit/bin/jskit.js"
|
|
12
|
-
},
|
|
13
10
|
"scripts": {
|
|
14
|
-
"server": "
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"
|
|
11
|
+
"server": "node ./bin/server.js",
|
|
12
|
+
"server:all": "node ./bin/server.js",
|
|
13
|
+
"server:home": "SERVER_SURFACE=home node ./bin/server.js",
|
|
14
|
+
"server:console": "SERVER_SURFACE=console node ./bin/server.js",
|
|
15
|
+
"server:account": "SERVER_SURFACE=account node ./bin/server.js",
|
|
16
|
+
"server:auth": "SERVER_SURFACE=auth node ./bin/server.js",
|
|
17
|
+
"server:app": "SERVER_SURFACE=app node ./bin/server.js",
|
|
18
|
+
"server:admin": "SERVER_SURFACE=admin node ./bin/server.js",
|
|
19
|
+
"start": "node ./bin/server.js",
|
|
20
|
+
"link:local:jskit": "bash ./scripts/link-local-jskit-packages.sh",
|
|
21
|
+
"verdaccio:reset:publish": "bash ./scripts/verdaccio-reset-and-publish-packages.sh",
|
|
22
|
+
"dev": "vite",
|
|
23
|
+
"dev:all": "vite",
|
|
24
|
+
"dev:home": "VITE_SURFACE=home vite",
|
|
25
|
+
"dev:console": "VITE_SURFACE=console vite",
|
|
26
|
+
"dev:account": "VITE_SURFACE=account vite",
|
|
27
|
+
"dev:auth": "VITE_SURFACE=auth vite",
|
|
28
|
+
"dev:app": "VITE_SURFACE=app vite",
|
|
29
|
+
"dev:admin": "VITE_SURFACE=admin vite",
|
|
30
|
+
"build": "vite build",
|
|
31
|
+
"build:all": "vite build",
|
|
32
|
+
"build:home": "VITE_SURFACE=home vite build",
|
|
33
|
+
"build:console": "VITE_SURFACE=console vite build",
|
|
34
|
+
"build:account": "VITE_SURFACE=account vite build",
|
|
35
|
+
"build:auth": "VITE_SURFACE=auth vite build",
|
|
36
|
+
"build:app": "VITE_SURFACE=app vite build",
|
|
37
|
+
"build:admin": "VITE_SURFACE=admin vite build",
|
|
38
|
+
"preview": "vite preview",
|
|
39
|
+
"lint": "eslint .",
|
|
40
|
+
"test": "node --test",
|
|
41
|
+
"test:client": "vitest run tests/client",
|
|
42
|
+
"preinstall": "bash ./scripts/dev-bootstrap-jskit.sh",
|
|
43
|
+
"jskit:update": "bash ./scripts/update-jskit-packages.sh"
|
|
23
44
|
},
|
|
24
45
|
"dependencies": {
|
|
25
|
-
"@
|
|
26
|
-
"@
|
|
27
|
-
"@jskit-ai/
|
|
46
|
+
"@local/main": "file:packages/main",
|
|
47
|
+
"@fastify/type-provider-typebox": "^6.1.0",
|
|
48
|
+
"@jskit-ai/kernel": "0.1.4",
|
|
28
49
|
"fastify": "^5.7.4",
|
|
29
|
-
"vue": "^3.5.13"
|
|
50
|
+
"vue": "^3.5.13",
|
|
51
|
+
"vue-router": "^4.6.4",
|
|
52
|
+
"vuetify": "^4.0.0",
|
|
53
|
+
"@jskit-ai/http-runtime": "0.1.4"
|
|
30
54
|
},
|
|
31
55
|
"devDependencies": {
|
|
32
|
-
"@jskit-ai/config-eslint": "0.1.
|
|
33
|
-
"@jskit-ai/jskit": "
|
|
56
|
+
"@jskit-ai/config-eslint": "0.1.4",
|
|
57
|
+
"@jskit-ai/jskit-cli": "0.2.4",
|
|
34
58
|
"@vitejs/plugin-vue": "^5.2.1",
|
|
35
59
|
"eslint": "^9.39.1",
|
|
60
|
+
"unplugin-vue-router": "^0.19.2",
|
|
36
61
|
"vite": "^6.1.0",
|
|
37
62
|
"vitest": "^4.0.18"
|
|
38
63
|
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export default Object.freeze({
|
|
2
|
+
packageVersion: 1,
|
|
3
|
+
packageId: "@local/main",
|
|
4
|
+
version: "0.1.0",
|
|
5
|
+
description: "App-local main module scaffold.",
|
|
6
|
+
dependsOn: [],
|
|
7
|
+
capabilities: {
|
|
8
|
+
provides: [],
|
|
9
|
+
requires: []
|
|
10
|
+
},
|
|
11
|
+
options: {},
|
|
12
|
+
runtime: {
|
|
13
|
+
server: {
|
|
14
|
+
providerEntrypoint: "src/server/index.js",
|
|
15
|
+
providers: [
|
|
16
|
+
{
|
|
17
|
+
discover: {
|
|
18
|
+
dir: "src/server/providers",
|
|
19
|
+
pattern: "*Provider.js"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
]
|
|
23
|
+
},
|
|
24
|
+
client: {
|
|
25
|
+
providers: [
|
|
26
|
+
{
|
|
27
|
+
entrypoint: "src/client/providers/MainClientProvider.js",
|
|
28
|
+
export: "MainClientProvider"
|
|
29
|
+
}
|
|
30
|
+
]
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
metadata: {
|
|
34
|
+
server: {
|
|
35
|
+
routes: []
|
|
36
|
+
},
|
|
37
|
+
ui: {
|
|
38
|
+
routes: [],
|
|
39
|
+
elements: [],
|
|
40
|
+
overrides: []
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
mutations: {
|
|
44
|
+
dependencies: {
|
|
45
|
+
runtime: {},
|
|
46
|
+
dev: {}
|
|
47
|
+
},
|
|
48
|
+
packageJson: {
|
|
49
|
+
scripts: {}
|
|
50
|
+
},
|
|
51
|
+
procfile: {},
|
|
52
|
+
text: [],
|
|
53
|
+
files: []
|
|
54
|
+
}
|
|
55
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@local/main",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"exports": {
|
|
7
|
+
"./client": "./src/client/index.js",
|
|
8
|
+
"./server": "./src/server/index.js",
|
|
9
|
+
"./server/providers/MainServiceProvider": "./src/server/providers/MainServiceProvider.js",
|
|
10
|
+
"./shared": "./src/shared/index.js"
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client entrypoint for @local/main.
|
|
3
|
+
*
|
|
4
|
+
* Export browser-facing modules from here.
|
|
5
|
+
*
|
|
6
|
+
* Example:
|
|
7
|
+
* export { MainClientProvider } from "./providers/MainClientProvider.js";
|
|
8
|
+
* export { registerMainClientComponent } from "./providers/MainClientProvider.js";
|
|
9
|
+
*/
|
|
10
|
+
export {
|
|
11
|
+
MainClientProvider,
|
|
12
|
+
registerMainClientComponent
|
|
13
|
+
} from "./providers/MainClientProvider.js";
|