everything-dev 1.16.3 → 1.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/init.cjs +167 -87
- package/dist/cli/init.cjs.map +1 -1
- package/dist/cli/init.d.cts +14 -2
- package/dist/cli/init.d.cts.map +1 -1
- package/dist/cli/init.d.mts +14 -2
- package/dist/cli/init.d.mts.map +1 -1
- package/dist/cli/init.mjs +166 -88
- package/dist/cli/init.mjs.map +1 -1
- package/dist/cli/prompts.cjs +12 -14
- package/dist/cli/prompts.cjs.map +1 -1
- package/dist/cli/prompts.mjs +12 -14
- package/dist/cli/prompts.mjs.map +1 -1
- package/dist/cli/sync.cjs +3 -5
- package/dist/cli/sync.cjs.map +1 -1
- package/dist/cli/sync.mjs +3 -5
- package/dist/cli/sync.mjs.map +1 -1
- package/dist/cli/upgrade.cjs +214 -2
- package/dist/cli/upgrade.cjs.map +1 -1
- package/dist/cli/upgrade.mjs +214 -2
- package/dist/cli/upgrade.mjs.map +1 -1
- package/dist/config.cjs +125 -74
- package/dist/config.cjs.map +1 -1
- package/dist/config.d.cts +9 -2
- package/dist/config.d.cts.map +1 -1
- package/dist/config.d.mts +9 -2
- package/dist/config.d.mts.map +1 -1
- package/dist/config.mjs +126 -76
- package/dist/config.mjs.map +1 -1
- package/dist/contract.cjs +1 -4
- package/dist/contract.cjs.map +1 -1
- package/dist/contract.d.cts +40 -22
- package/dist/contract.d.cts.map +1 -1
- package/dist/contract.d.mts +40 -22
- package/dist/contract.d.mts.map +1 -1
- package/dist/contract.meta.cjs +5 -5
- package/dist/contract.meta.cjs.map +1 -1
- package/dist/contract.meta.d.cts +9 -9
- package/dist/contract.meta.d.mts +9 -9
- package/dist/contract.meta.mjs +5 -5
- package/dist/contract.meta.mjs.map +1 -1
- package/dist/contract.mjs +1 -4
- package/dist/contract.mjs.map +1 -1
- package/dist/index.cjs +2 -0
- package/dist/index.d.cts +3 -3
- package/dist/index.d.mts +3 -3
- package/dist/index.mjs +3 -3
- package/dist/merge.cjs +1 -0
- package/dist/merge.mjs +1 -1
- package/dist/plugin.cjs +70 -114
- package/dist/plugin.cjs.map +1 -1
- package/dist/plugin.d.cts +38 -17
- package/dist/plugin.d.cts.map +1 -1
- package/dist/plugin.d.mts +38 -17
- package/dist/plugin.d.mts.map +1 -1
- package/dist/plugin.mjs +71 -115
- package/dist/plugin.mjs.map +1 -1
- package/dist/sidebar.cjs +6 -14
- package/dist/sidebar.cjs.map +1 -1
- package/dist/sidebar.d.cts +3 -3
- package/dist/sidebar.d.cts.map +1 -1
- package/dist/sidebar.d.mts +3 -3
- package/dist/sidebar.d.mts.map +1 -1
- package/dist/sidebar.mjs +6 -14
- package/dist/sidebar.mjs.map +1 -1
- package/dist/types.cjs +10 -16
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.cts +56 -12
- package/dist/types.d.cts.map +1 -1
- package/dist/types.d.mts +56 -12
- package/dist/types.d.mts.map +1 -1
- package/dist/types.mjs +10 -17
- package/dist/types.mjs.map +1 -1
- package/package.json +1 -1
- package/src/cli/init.ts +225 -131
- package/src/cli/prompts.ts +17 -22
- package/src/cli/sync.ts +5 -8
- package/src/cli/upgrade.ts +326 -2
- package/src/config.ts +250 -107
- package/src/contract.meta.ts +6 -8
- package/src/contract.ts +1 -4
- package/src/plugin.ts +120 -183
- package/src/sidebar.ts +9 -31
- package/src/types.ts +10 -15
package/src/config.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { dirname, isAbsolute, join, resolve } from "node:path";
|
|
|
3
3
|
import { fetchBosConfigFromFastKv } from "./fastkv";
|
|
4
4
|
import {
|
|
5
5
|
type BosEnv,
|
|
6
|
+
bosConfigMerger,
|
|
6
7
|
isPlainObject,
|
|
7
8
|
mergeBosConfigWithExtends,
|
|
8
9
|
type ResolvedConfigMeta,
|
|
@@ -18,7 +19,6 @@ import type {
|
|
|
18
19
|
PluginEntryValue,
|
|
19
20
|
RuntimeConfig,
|
|
20
21
|
RuntimePluginConfig,
|
|
21
|
-
SharedDepConfig,
|
|
22
22
|
} from "./types";
|
|
23
23
|
import { BosConfigSchema } from "./types";
|
|
24
24
|
|
|
@@ -74,6 +74,18 @@ export interface ConfigResult {
|
|
|
74
74
|
};
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
+
export interface ResolvedComposableReference {
|
|
78
|
+
entry: BosPluginRef;
|
|
79
|
+
providerBaseDir: string;
|
|
80
|
+
targetPath: string;
|
|
81
|
+
associatedUi?: Record<string, unknown>;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
interface ParsedExtendsTarget {
|
|
85
|
+
configPath: string;
|
|
86
|
+
targetPath?: string;
|
|
87
|
+
}
|
|
88
|
+
|
|
77
89
|
export async function loadConfig(options?: {
|
|
78
90
|
cwd?: string;
|
|
79
91
|
path?: string;
|
|
@@ -98,7 +110,11 @@ export async function loadConfig(options?: {
|
|
|
98
110
|
extendedChain,
|
|
99
111
|
env,
|
|
100
112
|
);
|
|
101
|
-
const config =
|
|
113
|
+
const config = await resolveRootComposableEntries(
|
|
114
|
+
BosConfigSchema.parse(parsed),
|
|
115
|
+
baseDir,
|
|
116
|
+
runtimeEnv,
|
|
117
|
+
);
|
|
102
118
|
|
|
103
119
|
cachedConfig = config;
|
|
104
120
|
projectRoot = baseDir;
|
|
@@ -144,6 +160,31 @@ export async function buildRuntimePluginsForConfig(
|
|
|
144
160
|
return Object.keys(plugins).length > 0 ? plugins : undefined;
|
|
145
161
|
}
|
|
146
162
|
|
|
163
|
+
async function resolveRootComposableEntries(
|
|
164
|
+
config: BosConfig,
|
|
165
|
+
baseDir: string,
|
|
166
|
+
env: BosEnv,
|
|
167
|
+
): Promise<BosConfig> {
|
|
168
|
+
const resolvedApi = await resolveComposableReference(
|
|
169
|
+
config.app.api as BosPluginRef,
|
|
170
|
+
baseDir,
|
|
171
|
+
env,
|
|
172
|
+
"app.api",
|
|
173
|
+
);
|
|
174
|
+
const resolvedAuth = config.app.auth
|
|
175
|
+
? await resolveComposableReference(config.app.auth as BosPluginRef, baseDir, env, "app.auth")
|
|
176
|
+
: undefined;
|
|
177
|
+
|
|
178
|
+
return {
|
|
179
|
+
...config,
|
|
180
|
+
app: {
|
|
181
|
+
...config.app,
|
|
182
|
+
api: resolvedApi.entry,
|
|
183
|
+
auth: resolvedAuth?.entry,
|
|
184
|
+
},
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
|
|
147
188
|
export function getResolvedConfigPath(configDir: string): string {
|
|
148
189
|
return join(configDir, ".bos", RESOLVED_CONFIG_FILENAME);
|
|
149
190
|
}
|
|
@@ -216,6 +257,173 @@ export function readBosConfigForBuild(configDir: string): Record<string, unknown
|
|
|
216
257
|
return JSON.parse(readFileSync(bosConfigPath, "utf-8")) as Record<string, unknown>;
|
|
217
258
|
}
|
|
218
259
|
|
|
260
|
+
function parseExtendsTarget(ref: string): ParsedExtendsTarget {
|
|
261
|
+
const hashIndex = ref.indexOf("#");
|
|
262
|
+
if (hashIndex === -1) {
|
|
263
|
+
return { configPath: ref };
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
const configPath = ref.slice(0, hashIndex);
|
|
267
|
+
const targetPath = ref.slice(hashIndex + 1);
|
|
268
|
+
return {
|
|
269
|
+
configPath,
|
|
270
|
+
targetPath: targetPath.length > 0 ? targetPath : undefined,
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
function getConfigBaseDir(configPath: string, baseDir: string): string {
|
|
275
|
+
if (configPath.startsWith("bos://")) return baseDir;
|
|
276
|
+
return dirname(isAbsolute(configPath) ? configPath : resolve(baseDir, configPath));
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
function asComposableEntry(value: unknown): BosPluginRef {
|
|
280
|
+
if (typeof value === "string") {
|
|
281
|
+
return { extends: value };
|
|
282
|
+
}
|
|
283
|
+
if (!isPlainObject(value)) {
|
|
284
|
+
throw new Error(`Expected config entry object, received ${typeof value}`);
|
|
285
|
+
}
|
|
286
|
+
return value as BosPluginRef;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
function getTargetedEntry(config: BosConfigInput, targetPath: string): BosPluginRef {
|
|
290
|
+
if (targetPath === "app.api") {
|
|
291
|
+
return asComposableEntry(config.app?.api);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
if (targetPath === "app.auth") {
|
|
295
|
+
return asComposableEntry(config.app?.auth);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
if (targetPath.startsWith("plugins.")) {
|
|
299
|
+
const pluginId = targetPath.slice("plugins.".length);
|
|
300
|
+
if (pluginId.length === 0) {
|
|
301
|
+
throw new Error(`Invalid plugin target path: ${targetPath}`);
|
|
302
|
+
}
|
|
303
|
+
return asComposableEntry(config.plugins?.[pluginId]);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
throw new Error(`Unsupported extends target path: ${targetPath}`);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
function getAssociatedUi(
|
|
310
|
+
config: BosConfigInput,
|
|
311
|
+
_targetPath: string,
|
|
312
|
+
): Record<string, unknown> | undefined {
|
|
313
|
+
return isPlainObject(config.app?.ui) ? (config.app.ui as Record<string, unknown>) : undefined;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
function mergeComposableEntries(
|
|
317
|
+
parent: Partial<BosPluginRef>,
|
|
318
|
+
child: Partial<BosPluginRef>,
|
|
319
|
+
): BosPluginRef {
|
|
320
|
+
return bosConfigMerger({ ...child }, parent) as BosPluginRef;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
function stripUnsafeLocalDevelopment<T extends Record<string, unknown> | undefined>(
|
|
324
|
+
entry: T,
|
|
325
|
+
allowLocalPaths: boolean,
|
|
326
|
+
): T {
|
|
327
|
+
if (!entry || allowLocalPaths) {
|
|
328
|
+
return entry;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
if (typeof entry.development === "string" && entry.development.startsWith(LOCAL_PREFIX)) {
|
|
332
|
+
const { development: _ignored, ...rest } = entry;
|
|
333
|
+
return rest as T;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
return entry;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
export async function resolveComposableReference(
|
|
340
|
+
source: BosPluginRef,
|
|
341
|
+
baseDir: string,
|
|
342
|
+
env: BosEnv,
|
|
343
|
+
defaultTargetPath: string,
|
|
344
|
+
): Promise<ResolvedComposableReference> {
|
|
345
|
+
let resolvedEntry: BosPluginRef = {};
|
|
346
|
+
let providerBaseDir = baseDir;
|
|
347
|
+
let targetPath = defaultTargetPath;
|
|
348
|
+
let associatedUi: Record<string, unknown> | undefined;
|
|
349
|
+
let allowLocalPaths = false;
|
|
350
|
+
let extendsError: unknown;
|
|
351
|
+
|
|
352
|
+
const extendsRef = source.extends ? resolveExtendsRef(source.extends, env) : undefined;
|
|
353
|
+
if (extendsRef) {
|
|
354
|
+
const parsed = parseExtendsTarget(extendsRef);
|
|
355
|
+
targetPath = parsed.targetPath ?? defaultTargetPath;
|
|
356
|
+
const extendsBaseDir = getConfigBaseDir(parsed.configPath, baseDir);
|
|
357
|
+
try {
|
|
358
|
+
const extendedConfig = await resolveConfigWithExtends(
|
|
359
|
+
parsed.configPath,
|
|
360
|
+
extendsBaseDir,
|
|
361
|
+
new Set(),
|
|
362
|
+
[],
|
|
363
|
+
env,
|
|
364
|
+
);
|
|
365
|
+
resolvedEntry = mergeComposableEntries(
|
|
366
|
+
resolvedEntry,
|
|
367
|
+
getTargetedEntry(extendedConfig, targetPath),
|
|
368
|
+
);
|
|
369
|
+
providerBaseDir = extendsBaseDir;
|
|
370
|
+
associatedUi = getAssociatedUi(extendedConfig, targetPath);
|
|
371
|
+
} catch (error) {
|
|
372
|
+
extendsError = error;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
const localDevelopment =
|
|
377
|
+
typeof source.development === "string" && source.development.startsWith(LOCAL_PREFIX)
|
|
378
|
+
? source.development
|
|
379
|
+
: undefined;
|
|
380
|
+
|
|
381
|
+
if (localDevelopment) {
|
|
382
|
+
const localPath = resolve(baseDir, localDevelopment.slice(LOCAL_PREFIX.length).trim());
|
|
383
|
+
const localConfigPath = join(localPath, "bos.config.json");
|
|
384
|
+
if (existsSync(localConfigPath)) {
|
|
385
|
+
const localConfig = await resolveConfigWithExtends(
|
|
386
|
+
localConfigPath,
|
|
387
|
+
localPath,
|
|
388
|
+
new Set(),
|
|
389
|
+
[],
|
|
390
|
+
env,
|
|
391
|
+
);
|
|
392
|
+
resolvedEntry = mergeComposableEntries(
|
|
393
|
+
resolvedEntry,
|
|
394
|
+
getTargetedEntry(localConfig, targetPath),
|
|
395
|
+
);
|
|
396
|
+
providerBaseDir = localPath;
|
|
397
|
+
associatedUi = getAssociatedUi(localConfig, targetPath);
|
|
398
|
+
allowLocalPaths = true;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
const sourceOverrides = { ...source };
|
|
403
|
+
if (allowLocalPaths && localDevelopment) {
|
|
404
|
+
delete sourceOverrides.development;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
resolvedEntry = mergeComposableEntries(resolvedEntry, sourceOverrides);
|
|
408
|
+
|
|
409
|
+
if (
|
|
410
|
+
extendsError &&
|
|
411
|
+
!allowLocalPaths &&
|
|
412
|
+
typeof resolvedEntry.development !== "string" &&
|
|
413
|
+
typeof resolvedEntry.production !== "string" &&
|
|
414
|
+
typeof resolvedEntry.name !== "string"
|
|
415
|
+
) {
|
|
416
|
+
throw extendsError;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
return {
|
|
420
|
+
entry: stripUnsafeLocalDevelopment(resolvedEntry, allowLocalPaths || Boolean(localDevelopment)),
|
|
421
|
+
providerBaseDir,
|
|
422
|
+
targetPath,
|
|
423
|
+
associatedUi: stripUnsafeLocalDevelopment(associatedUi, allowLocalPaths),
|
|
424
|
+
};
|
|
425
|
+
}
|
|
426
|
+
|
|
219
427
|
function resolveDevelopmentTarget(
|
|
220
428
|
development: string | undefined,
|
|
221
429
|
production: string | undefined,
|
|
@@ -225,6 +433,9 @@ function resolveDevelopmentTarget(
|
|
|
225
433
|
if (forceSource === "remote") {
|
|
226
434
|
return resolveRuntimeTarget(production, baseDir, "remote");
|
|
227
435
|
}
|
|
436
|
+
if (!development) {
|
|
437
|
+
return resolveRuntimeTarget(production, baseDir, "remote");
|
|
438
|
+
}
|
|
228
439
|
const devTarget = resolveRuntimeTarget(development, baseDir);
|
|
229
440
|
if (devTarget.source === "local" && (!devTarget.localPath || !existsSync(devTarget.localPath))) {
|
|
230
441
|
return resolveRuntimeTarget(production, baseDir, "remote");
|
|
@@ -298,6 +509,7 @@ export function buildRuntimeConfig(
|
|
|
298
509
|
const hostIsRemote = hostRuntime.source === "remote";
|
|
299
510
|
const uiIsRemote = uiRuntime.source === "remote";
|
|
300
511
|
const apiIsRemote = apiRuntime.source === "remote";
|
|
512
|
+
const resolvedApiName = resolvePluginRuntimeName(apiConfig.name, apiRuntime.localPath, "api");
|
|
301
513
|
|
|
302
514
|
return {
|
|
303
515
|
env,
|
|
@@ -331,7 +543,7 @@ export function buildRuntimeConfig(
|
|
|
331
543
|
source: uiRuntime.source,
|
|
332
544
|
},
|
|
333
545
|
api: {
|
|
334
|
-
name:
|
|
546
|
+
name: resolvedApiName,
|
|
335
547
|
url: apiRuntime.url,
|
|
336
548
|
entry: apiRuntime.url ? `${apiRuntime.url}/mf-manifest.json` : "/mf-manifest.json",
|
|
337
549
|
localPath: apiRuntime.localPath,
|
|
@@ -345,7 +557,7 @@ export function buildRuntimeConfig(
|
|
|
345
557
|
auth: (() => {
|
|
346
558
|
if (!authConfig || !authRuntime) return undefined;
|
|
347
559
|
return {
|
|
348
|
-
name: resolvePluginRuntimeName(
|
|
560
|
+
name: resolvePluginRuntimeName(authConfig.name, authRuntime.localPath, "auth"),
|
|
349
561
|
url: authRuntime.url,
|
|
350
562
|
entry: authRuntime.url ? `${authRuntime.url}/mf-manifest.json` : "/mf-manifest.json",
|
|
351
563
|
localPath: authRuntime.localPath,
|
|
@@ -399,14 +611,18 @@ async function resolveConfigWithExtends(
|
|
|
399
611
|
return config;
|
|
400
612
|
}
|
|
401
613
|
|
|
614
|
+
const parsedParentRef = parseExtendsTarget(extendsRef);
|
|
615
|
+
|
|
402
616
|
const nextVisited = new Set(visited);
|
|
403
617
|
nextVisited.add(configPath);
|
|
404
|
-
const parentBaseDir =
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
618
|
+
const parentBaseDir = getConfigBaseDir(parsedParentRef.configPath, baseDir);
|
|
619
|
+
const parent = await resolveConfigWithExtends(
|
|
620
|
+
parsedParentRef.configPath,
|
|
621
|
+
parentBaseDir,
|
|
622
|
+
nextVisited,
|
|
623
|
+
chain,
|
|
624
|
+
env,
|
|
625
|
+
);
|
|
410
626
|
|
|
411
627
|
return mergeBosConfigWithExtends(parent, config);
|
|
412
628
|
}
|
|
@@ -432,82 +648,20 @@ async function resolveRuntimePlugins(
|
|
|
432
648
|
const normalized = normalizePluginEntry(rawInput);
|
|
433
649
|
if (normalized === null || normalized === false) continue;
|
|
434
650
|
|
|
435
|
-
|
|
436
|
-
let pluginBaseDir = baseDir;
|
|
437
|
-
|
|
438
|
-
if (normalized.extends) {
|
|
439
|
-
try {
|
|
440
|
-
const extendsUrl = resolveExtendsRef(normalized.extends, env);
|
|
441
|
-
if (extendsUrl) {
|
|
442
|
-
const remoteConfig = await fetchBosConfigFromFastKv<BosConfigInput>(extendsUrl);
|
|
443
|
-
resolvedConfig = remoteConfig;
|
|
444
|
-
}
|
|
445
|
-
} catch {
|
|
446
|
-
resolvedConfig = {};
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
if (normalized.development?.startsWith(LOCAL_PREFIX)) {
|
|
451
|
-
const localPath = resolve(baseDir, normalized.development.slice(LOCAL_PREFIX.length).trim());
|
|
452
|
-
if (existsSync(localPath)) {
|
|
453
|
-
const localConfigPath = join(localPath, "bos.config.json");
|
|
454
|
-
if (existsSync(localConfigPath)) {
|
|
455
|
-
try {
|
|
456
|
-
const localRaw = JSON.parse(readFileSync(localConfigPath, "utf-8")) as BosConfigInput;
|
|
457
|
-
resolvedConfig = mergeBosConfigWithExtends(resolvedConfig, localRaw);
|
|
458
|
-
pluginBaseDir = localPath;
|
|
459
|
-
} catch {}
|
|
460
|
-
}
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
if (normalized.app && isPlainObject(normalized.app)) {
|
|
465
|
-
const mergedApp: Record<string, unknown> = {
|
|
466
|
-
...((resolvedConfig.app as Record<string, unknown>) ?? {}),
|
|
467
|
-
...(normalized.app as Record<string, unknown>),
|
|
468
|
-
};
|
|
469
|
-
resolvedConfig = { ...resolvedConfig, app: mergedApp as BosConfigInput["app"] };
|
|
470
|
-
}
|
|
471
|
-
if (normalized.shared && isPlainObject(normalized.shared)) {
|
|
472
|
-
const mergedShared: Record<string, Record<string, SharedDepConfig>> = {
|
|
473
|
-
...(resolvedConfig.shared ?? {}),
|
|
474
|
-
...(normalized.shared as Record<string, Record<string, SharedDepConfig>>),
|
|
475
|
-
};
|
|
476
|
-
resolvedConfig = { ...resolvedConfig, shared: mergedShared };
|
|
477
|
-
}
|
|
478
|
-
if (normalized.sidebar) {
|
|
479
|
-
resolvedConfig = { ...resolvedConfig, sidebar: normalized.sidebar };
|
|
480
|
-
}
|
|
481
|
-
if (normalized.routes) {
|
|
482
|
-
resolvedConfig = { ...resolvedConfig, routes: normalized.routes };
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
const pluginRuntime = await buildRuntimePluginConfig(
|
|
486
|
-
pluginId,
|
|
487
|
-
resolvedConfig,
|
|
488
|
-
pluginBaseDir,
|
|
489
|
-
env,
|
|
651
|
+
const resolvedReference = await resolveComposableReference(
|
|
490
652
|
normalized,
|
|
653
|
+
baseDir,
|
|
654
|
+
env,
|
|
655
|
+
`plugins.${pluginId}`,
|
|
491
656
|
);
|
|
492
|
-
if (
|
|
493
|
-
normalized.name &&
|
|
494
|
-
typeof normalized.name === "string" &&
|
|
495
|
-
!pluginRuntime.name.includes("/")
|
|
496
|
-
) {
|
|
497
|
-
pluginRuntime.name = normalized.name;
|
|
498
|
-
}
|
|
499
657
|
|
|
500
|
-
const
|
|
501
|
-
if (env === "production" && integrity) {
|
|
502
|
-
pluginRuntime.integrity = integrity;
|
|
503
|
-
}
|
|
658
|
+
const pluginRuntime = buildRuntimePluginConfig(pluginId, env, resolvedReference);
|
|
504
659
|
|
|
505
660
|
if (
|
|
506
661
|
pluginRuntime.source === "remote" &&
|
|
507
662
|
pluginRuntime.url &&
|
|
508
663
|
!pluginRuntime.localPath &&
|
|
509
|
-
typeof
|
|
510
|
-
!normalized.name
|
|
664
|
+
typeof resolvedReference.entry.name !== "string"
|
|
511
665
|
) {
|
|
512
666
|
pluginRuntime.name = await resolveRemotePluginRuntimeName(
|
|
513
667
|
pluginRuntime.url,
|
|
@@ -546,22 +700,14 @@ async function resolveRemotePluginRuntimeName(baseUrl: string, fallback: string)
|
|
|
546
700
|
}
|
|
547
701
|
}
|
|
548
702
|
|
|
549
|
-
|
|
703
|
+
function buildRuntimePluginConfig(
|
|
550
704
|
pluginId: string,
|
|
551
|
-
config: BosConfigInput,
|
|
552
|
-
baseDir: string,
|
|
553
705
|
env: BosEnv,
|
|
554
|
-
|
|
555
|
-
):
|
|
556
|
-
const
|
|
557
|
-
const
|
|
558
|
-
|
|
559
|
-
const apiProduction = typeof apiConfig.production === "string" ? apiConfig.production : undefined;
|
|
560
|
-
const sourceDevelopment = typeof source.development === "string" ? source.development : undefined;
|
|
561
|
-
const sourceProduction = typeof source.production === "string" ? source.production : undefined;
|
|
562
|
-
const proxy = typeof apiConfig.proxy === "string" ? apiConfig.proxy : undefined;
|
|
563
|
-
const development = apiDevelopment ?? sourceDevelopment;
|
|
564
|
-
const production = apiProduction ?? sourceProduction;
|
|
706
|
+
resolved: ResolvedComposableReference,
|
|
707
|
+
): RuntimePluginConfig {
|
|
708
|
+
const source = resolved.entry;
|
|
709
|
+
const development = typeof source.development === "string" ? source.development : undefined;
|
|
710
|
+
const production = typeof source.production === "string" ? source.production : undefined;
|
|
565
711
|
|
|
566
712
|
if (production?.startsWith("bos://")) {
|
|
567
713
|
throw new Error(
|
|
@@ -571,32 +717,28 @@ async function buildRuntimePluginConfig(
|
|
|
571
717
|
|
|
572
718
|
const runtimeTarget =
|
|
573
719
|
env === "development"
|
|
574
|
-
? resolveDevelopmentTarget(development, production,
|
|
575
|
-
: resolveRuntimeTarget(production,
|
|
576
|
-
const apiName = resolvePluginRuntimeName(
|
|
577
|
-
typeof apiConfig.name === "string" ? apiConfig.name : undefined,
|
|
578
|
-
runtimeTarget.localPath,
|
|
579
|
-
pluginId,
|
|
580
|
-
);
|
|
720
|
+
? resolveDevelopmentTarget(development, production, resolved.providerBaseDir)
|
|
721
|
+
: resolveRuntimeTarget(production, resolved.providerBaseDir, "remote");
|
|
722
|
+
const apiName = resolvePluginRuntimeName(source.name, runtimeTarget.localPath, pluginId);
|
|
581
723
|
|
|
582
|
-
const uiConfig =
|
|
724
|
+
const uiConfig = resolved.associatedUi;
|
|
583
725
|
const uiDevelopment =
|
|
584
726
|
typeof uiConfig?.development === "string" ? uiConfig.development : undefined;
|
|
585
727
|
const uiProduction = typeof uiConfig?.production === "string" ? uiConfig.production : undefined;
|
|
586
728
|
const uiRuntime =
|
|
587
729
|
uiConfig && (uiDevelopment || uiProduction)
|
|
588
730
|
? env === "development"
|
|
589
|
-
? resolveDevelopmentTarget(uiDevelopment, uiProduction,
|
|
590
|
-
: resolveRuntimeTarget(uiProduction,
|
|
731
|
+
? resolveDevelopmentTarget(uiDevelopment, uiProduction, resolved.providerBaseDir)
|
|
732
|
+
: resolveRuntimeTarget(uiProduction, resolved.providerBaseDir, "remote")
|
|
591
733
|
: undefined;
|
|
592
734
|
|
|
593
|
-
const sidebar =
|
|
735
|
+
const sidebar = source.sidebar?.map((item) => ({
|
|
594
736
|
...item,
|
|
595
737
|
to: item.to ?? `/${pluginId}`,
|
|
596
738
|
roleRequired: item.roleRequired ?? ("member" as const),
|
|
597
739
|
}));
|
|
598
740
|
|
|
599
|
-
const routes =
|
|
741
|
+
const routes = source.routes;
|
|
600
742
|
|
|
601
743
|
return {
|
|
602
744
|
name: apiName,
|
|
@@ -607,9 +749,10 @@ async function buildRuntimePluginConfig(
|
|
|
607
749
|
source: runtimeTarget.source,
|
|
608
750
|
localPath: runtimeTarget.localPath,
|
|
609
751
|
port: runtimeTarget.port,
|
|
610
|
-
proxy:
|
|
611
|
-
variables: normalizeStringRecord(
|
|
612
|
-
secrets: normalizeStringArray(
|
|
752
|
+
proxy: typeof source.proxy === "string" ? source.proxy : undefined,
|
|
753
|
+
variables: normalizeStringRecord(source.variables),
|
|
754
|
+
secrets: normalizeStringArray(source.secrets),
|
|
755
|
+
integrity: runtimeTarget.source === "remote" ? source.integrity : undefined,
|
|
613
756
|
ui: uiRuntime
|
|
614
757
|
? {
|
|
615
758
|
name: typeof uiConfig?.name === "string" ? uiConfig.name : `${apiName}-ui`,
|
package/src/contract.meta.ts
CHANGED
|
@@ -79,22 +79,20 @@ export const cliCommandMeta = {
|
|
|
79
79
|
},
|
|
80
80
|
init: {
|
|
81
81
|
commandPath: ["init"],
|
|
82
|
-
summary: "Scaffold a new project
|
|
82
|
+
summary: "Scaffold a new project by extending a deployed app or template",
|
|
83
83
|
interactive: true,
|
|
84
84
|
fields: {
|
|
85
85
|
domain: {
|
|
86
86
|
positional: true,
|
|
87
|
-
description: "New project domain (e.g.
|
|
87
|
+
description: "New project domain (e.g. myapp.everything.dev)",
|
|
88
88
|
},
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
description: "Parent NEAR account to extend from (defaults to dev.everything.near)",
|
|
92
|
-
},
|
|
93
|
-
extendsGateway: {
|
|
94
|
-
description: "Parent gateway to extend from (defaults to everything.dev)",
|
|
89
|
+
extends: {
|
|
90
|
+
description: "Parent to extend from (e.g. bos://account/gateway or account/gateway)",
|
|
95
91
|
},
|
|
92
|
+
account: { description: "New project NEAR account (auto-derived from extends)" },
|
|
96
93
|
directory: { description: "Target directory (auto-derived from domain)" },
|
|
97
94
|
source: { description: "Local source dir (skips GitHub download)" },
|
|
95
|
+
plugins: { description: "Comma-separated plugin keys to include" },
|
|
98
96
|
withHost: { description: "Include host/ in template output" },
|
|
99
97
|
noInteractive: { description: "Skip prompts, use flags only" },
|
|
100
98
|
noInstall: { description: "Skip bun install" },
|
package/src/contract.ts
CHANGED
|
@@ -144,8 +144,6 @@ export const KeyPublishResultSchema = z.object({
|
|
|
144
144
|
|
|
145
145
|
export const InitOptionsSchema = z.object({
|
|
146
146
|
extends: z.string().optional(),
|
|
147
|
-
extendsAccount: z.string().optional(),
|
|
148
|
-
extendsGateway: z.string().optional(),
|
|
149
147
|
directory: z.string().optional(),
|
|
150
148
|
account: z.string().optional(),
|
|
151
149
|
domain: z.string().optional(),
|
|
@@ -164,8 +162,7 @@ export const PhaseTimingSchema = z.object({
|
|
|
164
162
|
export const InitResultSchema = z.object({
|
|
165
163
|
status: z.enum(["initialized", "error"]),
|
|
166
164
|
directory: z.string(),
|
|
167
|
-
|
|
168
|
-
extendsGateway: z.string(),
|
|
165
|
+
extendsRef: z.string(),
|
|
169
166
|
account: z.string().optional(),
|
|
170
167
|
domain: z.string().optional(),
|
|
171
168
|
extends: z.string(),
|