@openfairygui/functions 0.2.0-alpha.7 → 0.2.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/README.md +52 -6
- package/dist/atlas-C6tbl7nn.d.ts +193 -0
- package/dist/atlas-CHsu2Y8i.d.cts +193 -0
- package/dist/index.cjs +17 -3603
- package/dist/index.d.cts +5 -294
- package/dist/index.d.ts +5 -294
- package/dist/index.js +4 -3595
- package/dist/node.cjs +256 -0
- package/dist/node.d.cts +36 -0
- package/dist/node.d.ts +36 -0
- package/dist/node.js +254 -0
- package/dist/publish-CykUJfVa.cjs +3269 -0
- package/dist/publish-DXoaC1Nl.js +3174 -0
- package/dist/restore-BQp01WY3.js +914 -0
- package/dist/restore-BeWaJNjR.d.cts +288 -0
- package/dist/restore-CEywQUHz.cjs +919 -0
- package/dist/restore-Dh0-Nvms.d.ts +288 -0
- package/dist/uam-transaction.cjs +29 -14
- package/dist/uam-transaction.d.cts +2 -1
- package/dist/uam-transaction.d.ts +2 -1
- package/dist/uam-transaction.js +30 -16
- package/dist/web.cjs +440 -0
- package/dist/web.d.cts +44 -0
- package/dist/web.d.ts +44 -0
- package/dist/web.js +439 -0
- package/package.json +29 -4
- package/src/adapters/node/plugins.ts +82 -0
- package/src/adapters/node/publish.ts +130 -0
- package/src/adapters/node/restore.ts +187 -0
- package/src/adapters/web/publish.ts +196 -0
- package/src/adapters/web/raster.ts +421 -0
- package/src/atlas/font.ts +95 -0
- package/src/atlas/inputs.ts +445 -0
- package/src/atlas/jta.ts +157 -0
- package/src/atlas/packing.ts +762 -0
- package/src/atlas.ts +129 -1221
- package/src/codegen.ts +108 -82
- package/src/index.ts +43 -3
- package/src/node.ts +8 -0
- package/src/path-utils.ts +40 -0
- package/src/plugins/types.ts +56 -0
- package/src/publish/contracts.ts +80 -0
- package/src/publish/external-resources.ts +117 -0
- package/src/publish/options.ts +180 -0
- package/src/publish/package-context.ts +608 -0
- package/src/publish/resource-references.ts +210 -0
- package/src/publish.ts +327 -975
- package/src/restore-internals/font.ts +100 -0
- package/src/restore-internals/movie-clip.ts +104 -0
- package/src/restore-internals/output-transaction.ts +124 -0
- package/src/restore.ts +122 -311
- package/src/shared-types.ts +4 -8
- package/src/uam-transaction.ts +34 -17
- package/src/utils.ts +28 -0
- package/src/web.ts +11 -0
package/src/codegen.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
type Component,
|
|
3
|
-
type GComponent,
|
|
4
3
|
type Document,
|
|
4
|
+
type GComponent,
|
|
5
5
|
type GObject,
|
|
6
6
|
type Package,
|
|
7
7
|
ProjectType,
|
|
@@ -12,7 +12,10 @@ import {
|
|
|
12
12
|
UNITY_BINDER_TEMPLATE,
|
|
13
13
|
UNITY_COMPONENT_TEMPLATE,
|
|
14
14
|
} from './codegen-templates.js';
|
|
15
|
-
import
|
|
15
|
+
import { formatPluginError, type LoadedPlugin } from './plugins/types.js';
|
|
16
|
+
import { dirname, isAbsolutePathLike, trimTrailingSlashes } from './path-utils.js';
|
|
17
|
+
import type { PublishFileSystem } from './publish/contracts.js';
|
|
18
|
+
import type { CliCodeGenerationSettings, RootProjectSettings } from './shared-types.js';
|
|
16
19
|
|
|
17
20
|
export const AUTO_GENERATED_CODE_MARK = '/** This is an automatically generated class by FairyGUI. Please do not modify it. **/';
|
|
18
21
|
const DEFAULT_CLASS_NAME_PREFIX = 'UI_';
|
|
@@ -22,25 +25,15 @@ export interface PublishCodeGenerationOptions {
|
|
|
22
25
|
basePath?: string;
|
|
23
26
|
fs: PublishFileSystem;
|
|
24
27
|
packages: Package[];
|
|
28
|
+
plugins?: LoadedPlugin[];
|
|
25
29
|
}
|
|
26
30
|
|
|
27
|
-
interface
|
|
28
|
-
allowGenCode: boolean;
|
|
29
|
-
classNamePrefix: string;
|
|
30
|
-
memberNamePrefix: string;
|
|
31
|
-
packageName: string;
|
|
32
|
-
ignoreNoname: boolean;
|
|
33
|
-
getMemberByName: boolean;
|
|
34
|
-
codePath: string;
|
|
35
|
-
codeType: string;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
interface ResolvedPackageCodegenPlan {
|
|
31
|
+
export interface ResolvedPackageCodegenPlan {
|
|
39
32
|
outputDir: string;
|
|
40
33
|
packageFolderName: string;
|
|
41
34
|
packageNamespace: string;
|
|
42
35
|
binderClassName: string;
|
|
43
|
-
settings:
|
|
36
|
+
settings: CliCodeGenerationSettings;
|
|
44
37
|
}
|
|
45
38
|
|
|
46
39
|
interface FguiTypescriptVariant {
|
|
@@ -77,16 +70,22 @@ const SHARED_FGUI_TYPESCRIPT_VARIANT: FguiTypescriptVariant = {
|
|
|
77
70
|
runtimeNamespace: 'fgui',
|
|
78
71
|
};
|
|
79
72
|
|
|
80
|
-
interface CodegenMember {
|
|
73
|
+
export interface CodegenMember {
|
|
81
74
|
index: number;
|
|
82
75
|
kind: 'child' | 'controller' | 'transition';
|
|
83
76
|
name: string;
|
|
84
77
|
originalName: string;
|
|
85
78
|
type: string;
|
|
86
79
|
ignored: boolean;
|
|
80
|
+
referencedComponent?: CodegenReferencedComponent;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export interface CodegenReferencedComponent {
|
|
84
|
+
component: Component;
|
|
85
|
+
package: Package;
|
|
87
86
|
}
|
|
88
87
|
|
|
89
|
-
interface CodegenClass {
|
|
88
|
+
export interface CodegenClass {
|
|
90
89
|
classId: string;
|
|
91
90
|
className: string;
|
|
92
91
|
encodedClassName: string;
|
|
@@ -97,14 +96,28 @@ interface CodegenClass {
|
|
|
97
96
|
members: CodegenMember[];
|
|
98
97
|
}
|
|
99
98
|
|
|
100
|
-
export async function publishCodeGeneration(
|
|
101
|
-
doc: Document,
|
|
102
|
-
options: PublishCodeGenerationOptions,
|
|
103
|
-
): Promise<void> {
|
|
99
|
+
export async function publishCodeGeneration(doc: Document, options: PublishCodeGenerationOptions): Promise<void> {
|
|
104
100
|
const logger = doc.getLogger();
|
|
105
101
|
const settings = resolveCodeGenerationSettings(doc);
|
|
106
102
|
if (!settings.allowGenCode) return;
|
|
107
103
|
|
|
104
|
+
const plugins = options.plugins?.filter((plugin) => typeof plugin.plugin.genCode === 'function') ?? [];
|
|
105
|
+
if (plugins.length > 0) {
|
|
106
|
+
let handled = false;
|
|
107
|
+
for (const plugin of plugins) {
|
|
108
|
+
try {
|
|
109
|
+
await plugin.plugin.genCode(doc, settings, options);
|
|
110
|
+
handled = true;
|
|
111
|
+
logger.info(`publish: Generated code using plugin "${plugin.name}"`);
|
|
112
|
+
} catch (error) {
|
|
113
|
+
logger.warn(`publish: Code generation plugin "${plugin.name}" failed: ${formatPluginError(error)}`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
if (handled) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
108
121
|
for (const pkg of options.packages) {
|
|
109
122
|
if (!pkg.getGenCode()) continue;
|
|
110
123
|
|
|
@@ -129,7 +142,7 @@ export async function publishCodeGeneration(
|
|
|
129
142
|
}
|
|
130
143
|
}
|
|
131
144
|
|
|
132
|
-
function resolveCodeGenerationSettings(doc: Document):
|
|
145
|
+
export function resolveCodeGenerationSettings(doc: Document): Required<CliCodeGenerationSettings> {
|
|
133
146
|
const settings = (doc.getRoot().getSettings?.() ?? {}) as RootProjectSettings;
|
|
134
147
|
const publish = settings.publish ?? {};
|
|
135
148
|
const codeGeneration = publish.codeGeneration as CliCodeGenerationSettings | undefined;
|
|
@@ -159,11 +172,7 @@ function resolveCodeGenerationSettings(doc: Document): ResolvedCodeGenerationSet
|
|
|
159
172
|
};
|
|
160
173
|
}
|
|
161
174
|
|
|
162
|
-
function resolvePackageCodegenPlan(
|
|
163
|
-
pkg: Package,
|
|
164
|
-
settings: ResolvedCodeGenerationSettings,
|
|
165
|
-
options: PublishCodeGenerationOptions,
|
|
166
|
-
): ResolvedPackageCodegenPlan | null {
|
|
175
|
+
export function resolvePackageCodegenPlan(pkg: Package, settings: CliCodeGenerationSettings, options: PublishCodeGenerationOptions): ResolvedPackageCodegenPlan | null {
|
|
167
176
|
const rawCodePath = (pkg.getCodePath() || settings.codePath || '').trim();
|
|
168
177
|
if (!rawCodePath) return null;
|
|
169
178
|
|
|
@@ -276,17 +285,11 @@ async function cleanupGeneratedFiles(directory: string, fs: PublishFileSystem, e
|
|
|
276
285
|
}
|
|
277
286
|
}
|
|
278
287
|
|
|
279
|
-
function buildCodegenClasses(
|
|
280
|
-
|
|
281
|
-
pkg: Package,
|
|
282
|
-
plan: ResolvedPackageCodegenPlan,
|
|
283
|
-
): CodegenClass[] {
|
|
284
|
-
const exportedComponents = pkg.listComponents()
|
|
285
|
-
.filter((component) => component.getExported())
|
|
286
|
-
.sort((left, right) => left.getId().localeCompare(right.getId()));
|
|
288
|
+
export function buildCodegenClasses(doc: Document, pkg: Package, plan: ResolvedPackageCodegenPlan): CodegenClass[] {
|
|
289
|
+
const codegenComponents = pkg.listComponents().sort((left, right) => left.getId().localeCompare(right.getId()));
|
|
287
290
|
const generatedById = new Map<string, CodegenClass>();
|
|
288
291
|
|
|
289
|
-
for (const component of
|
|
292
|
+
for (const component of codegenComponents) {
|
|
290
293
|
const encodedClassName = `${plan.settings.classNamePrefix}${normalizeTypeName(component.getName()) || 'Component'}`;
|
|
291
294
|
generatedById.set(component.getId(), {
|
|
292
295
|
classId: component.getId(),
|
|
@@ -300,7 +303,19 @@ function buildCodegenClasses(
|
|
|
300
303
|
});
|
|
301
304
|
}
|
|
302
305
|
|
|
303
|
-
for (const component of
|
|
306
|
+
for (const component of codegenComponents) {
|
|
307
|
+
const classInfo = generatedById.get(component.getId());
|
|
308
|
+
if (!classInfo) continue;
|
|
309
|
+
classInfo.members = buildCodegenMembers(doc, pkg, component, plan, generatedById);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
for (const [componentId, classInfo] of generatedById) {
|
|
313
|
+
if (classInfo.members.every((member) => member.ignored)) {
|
|
314
|
+
generatedById.delete(componentId);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
for (const component of codegenComponents) {
|
|
304
319
|
const classInfo = generatedById.get(component.getId());
|
|
305
320
|
if (!classInfo) continue;
|
|
306
321
|
classInfo.members = buildCodegenMembers(doc, pkg, component, plan, generatedById);
|
|
@@ -327,13 +342,17 @@ function buildCodegenMembers(
|
|
|
327
342
|
}
|
|
328
343
|
|
|
329
344
|
for (const child of component.listChildren()) {
|
|
345
|
+
if (!isRuntimeChild(child)) continue;
|
|
346
|
+
const index = childIndex++;
|
|
347
|
+
const resolvedChild = resolveChildType(doc, pkg, child, generatedById);
|
|
330
348
|
members.push(createMember(
|
|
331
349
|
ownerType,
|
|
332
350
|
'child',
|
|
333
|
-
|
|
351
|
+
resolvedChild.type,
|
|
334
352
|
child.getName(),
|
|
335
|
-
|
|
353
|
+
index,
|
|
336
354
|
plan,
|
|
355
|
+
resolvedChild.referencedComponent,
|
|
337
356
|
));
|
|
338
357
|
}
|
|
339
358
|
|
|
@@ -355,6 +374,10 @@ function buildCodegenMembers(
|
|
|
355
374
|
return members;
|
|
356
375
|
}
|
|
357
376
|
|
|
377
|
+
function isRuntimeChild(child: GObject): boolean {
|
|
378
|
+
return child.propertyType !== 'GGroup' || (child as GObject & { getAdvanced?(): boolean }).getAdvanced?.() === true;
|
|
379
|
+
}
|
|
380
|
+
|
|
358
381
|
function createMember(
|
|
359
382
|
ownerType: string,
|
|
360
383
|
kind: CodegenMember['kind'],
|
|
@@ -362,6 +385,7 @@ function createMember(
|
|
|
362
385
|
originalName: string,
|
|
363
386
|
index: number,
|
|
364
387
|
plan: ResolvedPackageCodegenPlan,
|
|
388
|
+
referencedComponent?: CodegenReferencedComponent,
|
|
365
389
|
): CodegenMember {
|
|
366
390
|
const ignored = plan.settings.ignoreNoname && isDefaultMemberName(ownerType, kind, originalName);
|
|
367
391
|
return {
|
|
@@ -371,43 +395,59 @@ function createMember(
|
|
|
371
395
|
originalName,
|
|
372
396
|
type,
|
|
373
397
|
ignored,
|
|
398
|
+
referencedComponent,
|
|
374
399
|
};
|
|
375
400
|
}
|
|
376
401
|
|
|
402
|
+
interface ResolvedChildCodegenType {
|
|
403
|
+
type: string;
|
|
404
|
+
referencedComponent?: CodegenReferencedComponent;
|
|
405
|
+
}
|
|
406
|
+
|
|
377
407
|
function resolveChildType(
|
|
378
408
|
doc: Document,
|
|
379
409
|
pkg: Package,
|
|
380
410
|
child: GObject,
|
|
381
411
|
generatedById: Map<string, CodegenClass>,
|
|
382
|
-
):
|
|
412
|
+
): ResolvedChildCodegenType {
|
|
383
413
|
const src = (child as GObject & { getSrc?(): string }).getSrc?.();
|
|
384
414
|
if (src) {
|
|
385
|
-
|
|
386
|
-
if (
|
|
387
|
-
|
|
388
|
-
|
|
415
|
+
let referencedComponent: CodegenReferencedComponent | null = null;
|
|
416
|
+
if (src.startsWith('ui://')) {
|
|
417
|
+
const rest = src.slice(5);
|
|
418
|
+
const pkgId = rest.slice(0, 8);
|
|
419
|
+
const resourceId = rest.slice(8);
|
|
420
|
+
const targetPackage = doc.getRoot().listPackages().find((candidate) => candidate.getId() === pkgId);
|
|
421
|
+
const targetResource = targetPackage?.getResourceById(resourceId);
|
|
422
|
+
if (targetPackage && targetResource?.propertyType === 'Component') {
|
|
423
|
+
referencedComponent = { component: targetResource, package: targetPackage };
|
|
424
|
+
}
|
|
425
|
+
} else {
|
|
426
|
+
const packageId = (child as GComponent & { getPackageId?(): string }).getPackageId?.();
|
|
427
|
+
const targetPackage = packageId
|
|
428
|
+
? doc.getRoot().listPackages().find((candidate) => candidate.getId() === packageId)
|
|
429
|
+
: pkg;
|
|
430
|
+
const targetResource = targetPackage?.getResourceById(src);
|
|
431
|
+
if (targetPackage && targetResource?.propertyType === 'Component') {
|
|
432
|
+
referencedComponent = { component: targetResource, package: targetPackage };
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
if (referencedComponent) {
|
|
437
|
+
const localGeneratedClass = referencedComponent.package === pkg
|
|
438
|
+
? generatedById.get(referencedComponent.component.getId())
|
|
439
|
+
: undefined;
|
|
440
|
+
return {
|
|
441
|
+
type: localGeneratedClass?.encodedClassName ?? resolveComponentBaseType(referencedComponent.component),
|
|
442
|
+
referencedComponent,
|
|
443
|
+
};
|
|
389
444
|
}
|
|
390
445
|
}
|
|
391
446
|
|
|
392
447
|
const instanceExtType = (child as GComponent & { getInstanceExtType?(): string }).getInstanceExtType?.();
|
|
393
|
-
if (instanceExtType) return `G${instanceExtType}
|
|
394
|
-
|
|
395
|
-
return child.propertyType;
|
|
396
|
-
}
|
|
448
|
+
if (instanceExtType) return { type: `G${instanceExtType}` };
|
|
397
449
|
|
|
398
|
-
|
|
399
|
-
if (!src) return null;
|
|
400
|
-
if (src.startsWith('ui://')) {
|
|
401
|
-
const rest = src.slice(5);
|
|
402
|
-
const pkgId = rest.slice(0, 8);
|
|
403
|
-
const resourceId = rest.slice(8);
|
|
404
|
-
const targetPackage = doc.getRoot().listPackages().find((candidate) => candidate.getId() === pkgId);
|
|
405
|
-
const targetResource = targetPackage?.getResourceById(resourceId);
|
|
406
|
-
return targetResource?.propertyType === 'Component' ? targetResource : null;
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
const localResource = pkg.getResourceById(src);
|
|
410
|
-
return localResource?.propertyType === 'Component' ? localResource : null;
|
|
450
|
+
return { type: child.propertyType };
|
|
411
451
|
}
|
|
412
452
|
|
|
413
453
|
function resolveComponentBaseType(component: Component): string {
|
|
@@ -544,12 +584,12 @@ function resolveCodePath(
|
|
|
544
584
|
basePath: string | undefined,
|
|
545
585
|
fs: Pick<PublishFileSystem, 'join'>,
|
|
546
586
|
): string {
|
|
547
|
-
if (
|
|
587
|
+
if (isAbsolutePathLike(codePath)) return trimTrailingSlashes(codePath);
|
|
548
588
|
const projectBasePath = resolveProjectBasePath(basePath);
|
|
549
589
|
return projectBasePath ? trimTrailingSlashes(fs.join(projectBasePath, codePath)) : trimTrailingSlashes(codePath);
|
|
550
590
|
}
|
|
551
591
|
|
|
552
|
-
function resolveProjectBasePath(basePath: string | undefined): string {
|
|
592
|
+
export function resolveProjectBasePath(basePath: string | undefined): string {
|
|
553
593
|
if (!basePath) return '';
|
|
554
594
|
const normalized = trimTrailingSlashes(basePath);
|
|
555
595
|
const assetsMatch = normalized.match(/^(.*)[/\\]assets(?:_[^/\\]+)?$/i);
|
|
@@ -557,20 +597,6 @@ function resolveProjectBasePath(basePath: string | undefined): string {
|
|
|
557
597
|
return dirname(normalized);
|
|
558
598
|
}
|
|
559
599
|
|
|
560
|
-
function dirname(filePath: string): string {
|
|
561
|
-
const trimmed = trimTrailingSlashes(filePath);
|
|
562
|
-
const match = trimmed.match(/^(.*)[/\\][^/\\]+$/);
|
|
563
|
-
return match?.[1] ?? '';
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
function trimTrailingSlashes(value: string): string {
|
|
567
|
-
return value.replace(/[/\\]+$/, '');
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
function isAbsolutePath(value: string): boolean {
|
|
571
|
-
return /^[a-z]:[/\\]/i.test(value) || value.startsWith('/') || value.startsWith('\\\\');
|
|
572
|
-
}
|
|
573
|
-
|
|
574
600
|
function isDefaultMemberName(ownerType: string, kind: CodegenMember['kind'], name: string): boolean {
|
|
575
601
|
if (kind === 'controller') {
|
|
576
602
|
return (ownerType === 'GButton' || ownerType === 'GComboBox') && name === 'button';
|
|
@@ -578,13 +604,13 @@ function isDefaultMemberName(ownerType: string, kind: CodegenMember['kind'], nam
|
|
|
578
604
|
if (kind === 'transition') return false;
|
|
579
605
|
|
|
580
606
|
if (ownerType === 'GButton' || ownerType === 'GLabel' || ownerType === 'GComboBox') {
|
|
581
|
-
|
|
607
|
+
if (name === 'title' || name === 'icon') return true;
|
|
582
608
|
}
|
|
583
609
|
if (ownerType === 'GProgressBar') {
|
|
584
|
-
|
|
610
|
+
if (name === 'bar' || name === 'bar_v' || name === 'title' || name === 'ani') return true;
|
|
585
611
|
}
|
|
586
612
|
if (ownerType === 'GSlider') {
|
|
587
|
-
|
|
613
|
+
if (name === 'bar' || name === 'bar_v' || name === 'grip' || name === 'title' || name === 'ani') return true;
|
|
588
614
|
}
|
|
589
615
|
return /^n\d+(?:_.*)?$/i.test(name);
|
|
590
616
|
}
|
|
@@ -647,10 +673,10 @@ async function writeTextFile(fs: PublishFileSystem, filePath: string, content: s
|
|
|
647
673
|
await fs.writeFileRaw(filePath, encodeText(content));
|
|
648
674
|
}
|
|
649
675
|
|
|
650
|
-
function encodeText(value: string): Uint8Array {
|
|
676
|
+
export function encodeText(value: string): Uint8Array {
|
|
651
677
|
return new TextEncoder().encode(value);
|
|
652
678
|
}
|
|
653
679
|
|
|
654
|
-
function decodeText(value: Uint8Array): string {
|
|
680
|
+
export function decodeText(value: Uint8Array): string {
|
|
655
681
|
return new TextDecoder().decode(value);
|
|
656
682
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,9 +1,48 @@
|
|
|
1
1
|
export { inspect, type InspectReport, type InspectCategoryReport } from './inspect.js';
|
|
2
|
-
export {
|
|
2
|
+
export {
|
|
3
|
+
validate,
|
|
4
|
+
type ValidateOptions,
|
|
5
|
+
type ValidationResult,
|
|
6
|
+
type ValidationIssue,
|
|
7
|
+
ValidationSeverity,
|
|
8
|
+
} from './validate.js';
|
|
3
9
|
export { prune, type PruneOptions } from './prune.js';
|
|
4
10
|
export { rename, type RenameOptions } from './rename.js';
|
|
5
11
|
export { atlas, type AtlasOptions } from './atlas.js';
|
|
6
|
-
export {
|
|
12
|
+
export {
|
|
13
|
+
publishCodeGeneration,
|
|
14
|
+
AUTO_GENERATED_CODE_MARK,
|
|
15
|
+
type PublishCodeGenerationOptions,
|
|
16
|
+
type ResolvedPackageCodegenPlan,
|
|
17
|
+
resolvePackageCodegenPlan,
|
|
18
|
+
buildCodegenClasses,
|
|
19
|
+
type CodegenClass,
|
|
20
|
+
type CodegenMember,
|
|
21
|
+
type CodegenReferencedComponent,
|
|
22
|
+
encodeText,
|
|
23
|
+
decodeText,
|
|
24
|
+
} from './codegen.js';
|
|
25
|
+
|
|
26
|
+
export type {
|
|
27
|
+
CodeWriter,
|
|
28
|
+
ICodeWriterConfig,
|
|
29
|
+
MaybePromise,
|
|
30
|
+
LoadedPlugin,
|
|
31
|
+
Plugin,
|
|
32
|
+
PluginManifest,
|
|
33
|
+
PluginModule,
|
|
34
|
+
} from './plugins/types.js';
|
|
35
|
+
export type {
|
|
36
|
+
AtlasRasterBackend,
|
|
37
|
+
AtlasRasterCompositeInput,
|
|
38
|
+
AtlasRasterInput,
|
|
39
|
+
AtlasRasterMetadata,
|
|
40
|
+
AtlasRasterPipeline,
|
|
41
|
+
AtlasRasterResolvedBuffer,
|
|
42
|
+
PublishFileSystem,
|
|
43
|
+
PublishOutputFileSystem,
|
|
44
|
+
PublishSourceFileSystem,
|
|
45
|
+
} from './publish/contracts.js';
|
|
7
46
|
export {
|
|
8
47
|
restore,
|
|
9
48
|
type RestoreFileSystem,
|
|
@@ -24,6 +63,7 @@ export {
|
|
|
24
63
|
} from './publish.js';
|
|
25
64
|
export {
|
|
26
65
|
applyUamTransactionApp,
|
|
66
|
+
applyUamTransactionAppAsync,
|
|
27
67
|
type ApplyUamTransactionAppDiagnostic,
|
|
28
68
|
type ApplyUamTransactionAppError,
|
|
29
69
|
type ApplyUamTransactionAppInput,
|
|
@@ -38,6 +78,6 @@ export type {
|
|
|
38
78
|
HasOptionalSrc,
|
|
39
79
|
HasOptionalUrl,
|
|
40
80
|
PublishDependency,
|
|
41
|
-
PublishFileSystem,
|
|
42
81
|
RootProjectSettings,
|
|
82
|
+
CliCodeGenerationSettings,
|
|
43
83
|
} from './shared-types.js';
|
package/src/node.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export function trimTrailingSlashes(value: string): string {
|
|
2
|
+
return value.replace(/[/\\]+$/, '');
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
export function dirname(filePath: string): string {
|
|
6
|
+
const match = trimTrailingSlashes(filePath).match(/^(.*)[/\\][^/\\]+$/);
|
|
7
|
+
return match?.[1] ?? '';
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export function basename(filePath: string): string {
|
|
11
|
+
const match = trimTrailingSlashes(filePath).match(/([^/\\]+)$/);
|
|
12
|
+
return match?.[1] ?? '';
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function isAbsolutePathLike(value: string): boolean {
|
|
16
|
+
return /^(?:[a-zA-Z]:[/\\]|[/\\]{1,2})/u.test(value);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function normalizeComparablePath(value: string): string {
|
|
20
|
+
const normalized = trimTrailingSlashes(value).replace(/\\/g, '/');
|
|
21
|
+
const driveMatch = normalized.match(/^([a-z]:)(?:\/(.*))?$/i);
|
|
22
|
+
const drivePrefix = driveMatch?.[1].toLowerCase() ?? '';
|
|
23
|
+
const remainder = driveMatch ? (driveMatch[2] ?? '') : normalized;
|
|
24
|
+
const hasRoot = driveMatch ? true : remainder.startsWith('/');
|
|
25
|
+
const segments: string[] = [];
|
|
26
|
+
|
|
27
|
+
for (const segment of remainder.split('/').filter(Boolean)) {
|
|
28
|
+
if (segment === '.') continue;
|
|
29
|
+
if (segment === '..') {
|
|
30
|
+
if (segments.length > 0 && segments.at(-1) !== '..') segments.pop();
|
|
31
|
+
else if (!hasRoot) segments.push('..');
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
segments.push(segment);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const joined = segments.join('/');
|
|
38
|
+
const comparable = drivePrefix ? `${drivePrefix}/${joined}` : hasRoot ? `/${joined}` : joined || '.';
|
|
39
|
+
return comparable.replace(/\/$/, '').toLowerCase();
|
|
40
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { Document } from '@openfairygui/core';
|
|
2
|
+
import type { PublishCodeGenerationOptions } from '../codegen.js';
|
|
3
|
+
import type { PublishOptions } from '../publish.js';
|
|
4
|
+
import type { CliCodeGenerationSettings } from '../shared-types.js';
|
|
5
|
+
|
|
6
|
+
export type MaybePromise<T> = T | Promise<T>;
|
|
7
|
+
|
|
8
|
+
export interface PluginManifest {
|
|
9
|
+
name: string;
|
|
10
|
+
displayName?: string;
|
|
11
|
+
description?: string;
|
|
12
|
+
version?: string;
|
|
13
|
+
author?: {
|
|
14
|
+
name?: string;
|
|
15
|
+
};
|
|
16
|
+
icon?: string;
|
|
17
|
+
main: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface ICodeWriterConfig {
|
|
21
|
+
blockStart?: string;
|
|
22
|
+
blockEnd?: string;
|
|
23
|
+
blockFromNewLine?: boolean;
|
|
24
|
+
usingTabs?: boolean;
|
|
25
|
+
endOfLine?: string;
|
|
26
|
+
fileMark?: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface CodeWriter {
|
|
30
|
+
writeMark(): void;
|
|
31
|
+
writeln(fmt?: string, ...args: any[]): CodeWriter;
|
|
32
|
+
startBlock(): CodeWriter;
|
|
33
|
+
endBlock(): CodeWriter;
|
|
34
|
+
incIndent(): CodeWriter;
|
|
35
|
+
decIndent(): CodeWriter;
|
|
36
|
+
reset(): void;
|
|
37
|
+
toString(): string;
|
|
38
|
+
save(filePath: string): void;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface Plugin {
|
|
42
|
+
genCode?: (doc: Document, settings: Required<CliCodeGenerationSettings>, options: PublishCodeGenerationOptions) => MaybePromise<void>;
|
|
43
|
+
onPublishStart?: (doc: Document, options: PublishOptions) => MaybePromise<void>;
|
|
44
|
+
onPublishEnd?: (doc: Document, options: PublishOptions) => MaybePromise<void>;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface LoadedPlugin {
|
|
48
|
+
name: string;
|
|
49
|
+
plugin: Plugin;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export type PluginModule = Plugin & { default?: Plugin };
|
|
53
|
+
|
|
54
|
+
export function formatPluginError(error: unknown): string {
|
|
55
|
+
return error instanceof Error ? error.message : String(error);
|
|
56
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { FileSystem } from '@openfairygui/core';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Source files required by a publish adapter.
|
|
5
|
+
*
|
|
6
|
+
* The host owns this filesystem: Node adapters use native paths while web
|
|
7
|
+
* adapters can use File System Access, OPFS, IndexedDB, ZIP, or memory.
|
|
8
|
+
*/
|
|
9
|
+
export type PublishSourceFileSystem = Pick<FileSystem, 'readFileRaw' | 'join'>;
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Output files required by a publish adapter.
|
|
13
|
+
*/
|
|
14
|
+
export type PublishOutputFileSystem = Pick<FileSystem, 'writeFileRaw' | 'mkdir' | 'join'>;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Full filesystem contract consumed by the capability-injected publish core.
|
|
18
|
+
*
|
|
19
|
+
* Read, enumeration, and delete operations are optional because individual
|
|
20
|
+
* publish lanes only request them when needed.
|
|
21
|
+
*/
|
|
22
|
+
export type PublishFileSystem = PublishOutputFileSystem & {
|
|
23
|
+
deleteFile?: (path: string) => Promise<void>;
|
|
24
|
+
exists?: FileSystem['exists'];
|
|
25
|
+
readdir?: FileSystem['readdir'];
|
|
26
|
+
readFileRaw?: FileSystem['readFileRaw'];
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export interface AtlasRasterMetadata {
|
|
30
|
+
width?: number;
|
|
31
|
+
height?: number;
|
|
32
|
+
channels?: number;
|
|
33
|
+
hasAlpha?: boolean;
|
|
34
|
+
trimOffsetLeft?: number;
|
|
35
|
+
trimOffsetTop?: number;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface AtlasRasterResolvedBuffer {
|
|
39
|
+
data: Uint8Array;
|
|
40
|
+
info: Required<Pick<AtlasRasterMetadata, 'width' | 'height' | 'channels'>> & AtlasRasterMetadata;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface AtlasRasterCompositeInput {
|
|
44
|
+
input: Uint8Array;
|
|
45
|
+
left: number;
|
|
46
|
+
top: number;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export type AtlasRasterInput =
|
|
50
|
+
| string
|
|
51
|
+
| Uint8Array
|
|
52
|
+
| {
|
|
53
|
+
create: {
|
|
54
|
+
width: number;
|
|
55
|
+
height: number;
|
|
56
|
+
channels: 4;
|
|
57
|
+
background: { r: number; g: number; b: number; alpha: number };
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Host-provided raster pipeline used by atlas packing.
|
|
63
|
+
*
|
|
64
|
+
* Sharp and the browser Canvas adapter both satisfy this contract.
|
|
65
|
+
*/
|
|
66
|
+
export interface AtlasRasterPipeline {
|
|
67
|
+
ensureAlpha(): AtlasRasterPipeline;
|
|
68
|
+
resize(options: { width: number; height: number; fit?: 'fill' }): AtlasRasterPipeline;
|
|
69
|
+
raw(): AtlasRasterPipeline;
|
|
70
|
+
extract(options: { left: number; top: number; width: number; height: number }): AtlasRasterPipeline;
|
|
71
|
+
png(): AtlasRasterPipeline;
|
|
72
|
+
rotate(angle: number): AtlasRasterPipeline;
|
|
73
|
+
composite(inputs: AtlasRasterCompositeInput[]): AtlasRasterPipeline;
|
|
74
|
+
metadata(): Promise<AtlasRasterMetadata>;
|
|
75
|
+
toBuffer(options: { resolveWithObject: true }): Promise<AtlasRasterResolvedBuffer>;
|
|
76
|
+
toBuffer(options?: { resolveWithObject?: false }): Promise<Uint8Array>;
|
|
77
|
+
toFile(path: string): Promise<unknown>;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export type AtlasRasterBackend = (input: AtlasRasterInput) => AtlasRasterPipeline;
|