@tanstack/cta-engine 0.15.0 → 0.15.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.
- package/dist/index.js +1 -1
- package/dist/registry.js +34 -9
- package/dist/types/index.d.ts +1 -1
- package/dist/types/registry.d.ts +71 -10
- package/dist/types/utils.d.ts +1 -0
- package/dist/utils.js +14 -0
- package/package.json +1 -1
- package/src/index.ts +1 -1
- package/src/registry.ts +41 -27
- package/src/utils.ts +15 -0
- package/tests/utils.test.ts +26 -1
package/dist/index.js
CHANGED
|
@@ -9,7 +9,7 @@ export { DEFAULT_PACKAGE_MANAGER, SUPPORTED_PACKAGE_MANAGERS, getPackageManager,
|
|
|
9
9
|
export { registerFramework, getFrameworkById, getFrameworkByName, getFrameworks, } from './frameworks.js';
|
|
10
10
|
export { writeConfigFileToEnvironment, readConfigFileFromEnvironment, readConfigFile, } from './config-file.js';
|
|
11
11
|
export { cleanUpFiles, cleanUpFileArray, readFileHelper, getBinaryFile, recursivelyGatherFiles, relativePath, } from './file-helpers.js';
|
|
12
|
-
export { formatCommand } from './utils.js';
|
|
12
|
+
export { formatCommand, handleSpecialURL } from './utils.js';
|
|
13
13
|
export { initStarter, compileStarter } from './custom-add-ons/starter.js';
|
|
14
14
|
export { initAddOn, compileAddOn } from './custom-add-ons/add-on.js';
|
|
15
15
|
export { createAppOptionsFromPersisted, createSerializedOptionsFromPersisted, } from './custom-add-ons/shared.js';
|
package/dist/registry.js
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
1
2
|
import { loadRemoteAddOn } from './custom-add-ons/add-on.js';
|
|
2
3
|
import { loadStarter } from './custom-add-ons/starter.js';
|
|
4
|
+
import { handleSpecialURL } from './utils.js';
|
|
5
|
+
const registrySchema = z.object({
|
|
6
|
+
starters: z
|
|
7
|
+
.array(z.object({
|
|
8
|
+
name: z.string(),
|
|
9
|
+
description: z.string(),
|
|
10
|
+
url: z.string(),
|
|
11
|
+
banner: z.string().optional(),
|
|
12
|
+
mode: z.enum(['code-router', 'file-router']),
|
|
13
|
+
framework: z.string(),
|
|
14
|
+
}))
|
|
15
|
+
.optional(),
|
|
16
|
+
'add-ons': z
|
|
17
|
+
.array(z.object({
|
|
18
|
+
name: z.string(),
|
|
19
|
+
description: z.string(),
|
|
20
|
+
url: z.string(),
|
|
21
|
+
modes: z.array(z.enum(['code-router', 'file-router'])),
|
|
22
|
+
framework: z.string(),
|
|
23
|
+
}))
|
|
24
|
+
.optional(),
|
|
25
|
+
});
|
|
3
26
|
function absolutizeUrl(originalUrl, relativeUrl) {
|
|
4
27
|
if (relativeUrl.startsWith('http') || relativeUrl.startsWith('https')) {
|
|
5
28
|
return relativeUrl;
|
|
@@ -10,22 +33,24 @@ function absolutizeUrl(originalUrl, relativeUrl) {
|
|
|
10
33
|
export async function getRawRegistry(registryUrl) {
|
|
11
34
|
const regUrl = registryUrl || process.env.CTA_REGISTRY;
|
|
12
35
|
if (regUrl) {
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
36
|
+
const url = handleSpecialURL(regUrl);
|
|
37
|
+
const registry = (await fetch(url).then((res) => res.json()));
|
|
38
|
+
const parsedRegistry = registrySchema.parse(registry);
|
|
39
|
+
for (const addOn of parsedRegistry['add-ons'] || []) {
|
|
40
|
+
addOn.url = absolutizeUrl(url, addOn.url);
|
|
16
41
|
}
|
|
17
|
-
for (const starter of
|
|
18
|
-
starter.url = absolutizeUrl(
|
|
42
|
+
for (const starter of parsedRegistry.starters || []) {
|
|
43
|
+
starter.url = absolutizeUrl(url, starter.url);
|
|
19
44
|
if (starter.banner) {
|
|
20
|
-
starter.banner = absolutizeUrl(
|
|
45
|
+
starter.banner = absolutizeUrl(url, starter.banner);
|
|
21
46
|
}
|
|
22
47
|
}
|
|
23
|
-
return
|
|
48
|
+
return parsedRegistry;
|
|
24
49
|
}
|
|
25
50
|
}
|
|
26
51
|
async function getAddOns(registry) {
|
|
27
52
|
const addOns = [];
|
|
28
|
-
for (const addOnInfo of registry['add-ons']) {
|
|
53
|
+
for (const addOnInfo of registry['add-ons'] || []) {
|
|
29
54
|
const addOn = await loadRemoteAddOn(addOnInfo.url);
|
|
30
55
|
addOns.push(addOn);
|
|
31
56
|
}
|
|
@@ -37,7 +62,7 @@ export async function getRegistryAddOns(registryUrl) {
|
|
|
37
62
|
}
|
|
38
63
|
async function getStarters(registry) {
|
|
39
64
|
const starters = [];
|
|
40
|
-
for (const starterInfo of registry.starters) {
|
|
65
|
+
for (const starterInfo of registry.starters || []) {
|
|
41
66
|
const starter = await loadStarter(starterInfo.url);
|
|
42
67
|
starters.push(starter);
|
|
43
68
|
}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ export { DEFAULT_PACKAGE_MANAGER, SUPPORTED_PACKAGE_MANAGERS, getPackageManager,
|
|
|
9
9
|
export { registerFramework, getFrameworkById, getFrameworkByName, getFrameworks, } from './frameworks.js';
|
|
10
10
|
export { writeConfigFileToEnvironment, readConfigFileFromEnvironment, readConfigFile, } from './config-file.js';
|
|
11
11
|
export { cleanUpFiles, cleanUpFileArray, readFileHelper, getBinaryFile, recursivelyGatherFiles, relativePath, } from './file-helpers.js';
|
|
12
|
-
export { formatCommand } from './utils.js';
|
|
12
|
+
export { formatCommand, handleSpecialURL } from './utils.js';
|
|
13
13
|
export { initStarter, compileStarter } from './custom-add-ons/starter.js';
|
|
14
14
|
export { initAddOn, compileAddOn } from './custom-add-ons/add-on.js';
|
|
15
15
|
export { createAppOptionsFromPersisted, createSerializedOptionsFromPersisted, } from './custom-add-ons/shared.js';
|
package/dist/types/registry.d.ts
CHANGED
|
@@ -1,21 +1,81 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { AddOn, Starter } from './types';
|
|
3
|
+
declare const registrySchema: z.ZodObject<{
|
|
4
|
+
starters: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
5
|
+
name: z.ZodString;
|
|
6
|
+
description: z.ZodString;
|
|
7
|
+
url: z.ZodString;
|
|
8
|
+
banner: z.ZodOptional<z.ZodString>;
|
|
9
|
+
mode: z.ZodEnum<["code-router", "file-router"]>;
|
|
10
|
+
framework: z.ZodString;
|
|
11
|
+
}, "strip", z.ZodTypeAny, {
|
|
4
12
|
name: string;
|
|
5
13
|
description: string;
|
|
6
14
|
url: string;
|
|
7
|
-
banner?: string;
|
|
8
|
-
mode: Mode;
|
|
9
15
|
framework: string;
|
|
10
|
-
|
|
11
|
-
|
|
16
|
+
mode: "code-router" | "file-router";
|
|
17
|
+
banner?: string | undefined;
|
|
18
|
+
}, {
|
|
12
19
|
name: string;
|
|
13
20
|
description: string;
|
|
14
21
|
url: string;
|
|
15
|
-
modes: Array<Mode>;
|
|
16
22
|
framework: string;
|
|
17
|
-
|
|
18
|
-
|
|
23
|
+
mode: "code-router" | "file-router";
|
|
24
|
+
banner?: string | undefined;
|
|
25
|
+
}>, "many">>;
|
|
26
|
+
'add-ons': z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
27
|
+
name: z.ZodString;
|
|
28
|
+
description: z.ZodString;
|
|
29
|
+
url: z.ZodString;
|
|
30
|
+
modes: z.ZodArray<z.ZodEnum<["code-router", "file-router"]>, "many">;
|
|
31
|
+
framework: z.ZodString;
|
|
32
|
+
}, "strip", z.ZodTypeAny, {
|
|
33
|
+
name: string;
|
|
34
|
+
description: string;
|
|
35
|
+
url: string;
|
|
36
|
+
framework: string;
|
|
37
|
+
modes: ("code-router" | "file-router")[];
|
|
38
|
+
}, {
|
|
39
|
+
name: string;
|
|
40
|
+
description: string;
|
|
41
|
+
url: string;
|
|
42
|
+
framework: string;
|
|
43
|
+
modes: ("code-router" | "file-router")[];
|
|
44
|
+
}>, "many">>;
|
|
45
|
+
}, "strip", z.ZodTypeAny, {
|
|
46
|
+
starters?: {
|
|
47
|
+
name: string;
|
|
48
|
+
description: string;
|
|
49
|
+
url: string;
|
|
50
|
+
framework: string;
|
|
51
|
+
mode: "code-router" | "file-router";
|
|
52
|
+
banner?: string | undefined;
|
|
53
|
+
}[] | undefined;
|
|
54
|
+
'add-ons'?: {
|
|
55
|
+
name: string;
|
|
56
|
+
description: string;
|
|
57
|
+
url: string;
|
|
58
|
+
framework: string;
|
|
59
|
+
modes: ("code-router" | "file-router")[];
|
|
60
|
+
}[] | undefined;
|
|
61
|
+
}, {
|
|
62
|
+
starters?: {
|
|
63
|
+
name: string;
|
|
64
|
+
description: string;
|
|
65
|
+
url: string;
|
|
66
|
+
framework: string;
|
|
67
|
+
mode: "code-router" | "file-router";
|
|
68
|
+
banner?: string | undefined;
|
|
69
|
+
}[] | undefined;
|
|
70
|
+
'add-ons'?: {
|
|
71
|
+
name: string;
|
|
72
|
+
description: string;
|
|
73
|
+
url: string;
|
|
74
|
+
framework: string;
|
|
75
|
+
modes: ("code-router" | "file-router")[];
|
|
76
|
+
}[] | undefined;
|
|
77
|
+
}>;
|
|
78
|
+
export type Registry = z.infer<typeof registrySchema>;
|
|
19
79
|
export declare function getRawRegistry(registryUrl?: string): Promise<Registry | undefined>;
|
|
20
80
|
export declare function getRegistryAddOns(registryUrl?: string): Promise<Array<AddOn>>;
|
|
21
81
|
export declare function getRegistryStarters(registryUrl?: string): Promise<Array<Starter>>;
|
|
@@ -23,3 +83,4 @@ export declare function getRegistry(registryUrl?: string): Promise<{
|
|
|
23
83
|
addOns: Array<AddOn>;
|
|
24
84
|
starters: Array<Starter>;
|
|
25
85
|
}>;
|
|
86
|
+
export {};
|
package/dist/types/utils.d.ts
CHANGED
package/dist/utils.js
CHANGED
|
@@ -15,3 +15,17 @@ export function jsSafeName(name) {
|
|
|
15
15
|
export function formatCommand({ command, args, }) {
|
|
16
16
|
return `${command} ${args.join(' ')}`.trim();
|
|
17
17
|
}
|
|
18
|
+
// Turn GitHub URLs into raw URLs
|
|
19
|
+
export function handleSpecialURL(url) {
|
|
20
|
+
if (url.startsWith('https://github.com/') && url.includes('blob')) {
|
|
21
|
+
return url
|
|
22
|
+
.replace('https://github.com/', 'https://raw.githubusercontent.com/')
|
|
23
|
+
.replace('/blob/', '/refs/heads/');
|
|
24
|
+
}
|
|
25
|
+
if (url.startsWith('https://github.com/') && url.includes('tree')) {
|
|
26
|
+
return url
|
|
27
|
+
.replace('https://github.com/', 'https://raw.githubusercontent.com/')
|
|
28
|
+
.replace('/tree/', '/refs/heads/');
|
|
29
|
+
}
|
|
30
|
+
return url;
|
|
31
|
+
}
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -41,7 +41,7 @@ export {
|
|
|
41
41
|
relativePath,
|
|
42
42
|
} from './file-helpers.js'
|
|
43
43
|
|
|
44
|
-
export { formatCommand } from './utils.js'
|
|
44
|
+
export { formatCommand, handleSpecialURL } from './utils.js'
|
|
45
45
|
|
|
46
46
|
export { initStarter, compileStarter } from './custom-add-ons/starter.js'
|
|
47
47
|
export { initAddOn, compileAddOn } from './custom-add-ons/add-on.js'
|
package/src/registry.ts
CHANGED
|
@@ -1,25 +1,37 @@
|
|
|
1
|
+
import { z } from 'zod'
|
|
1
2
|
import { loadRemoteAddOn } from './custom-add-ons/add-on.js'
|
|
2
3
|
import { loadStarter } from './custom-add-ons/starter.js'
|
|
4
|
+
import { handleSpecialURL } from './utils.js'
|
|
3
5
|
|
|
4
|
-
import type { AddOn,
|
|
6
|
+
import type { AddOn, Starter } from './types'
|
|
5
7
|
|
|
6
|
-
|
|
7
|
-
starters:
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
8
|
+
const registrySchema = z.object({
|
|
9
|
+
starters: z
|
|
10
|
+
.array(
|
|
11
|
+
z.object({
|
|
12
|
+
name: z.string(),
|
|
13
|
+
description: z.string(),
|
|
14
|
+
url: z.string(),
|
|
15
|
+
banner: z.string().optional(),
|
|
16
|
+
mode: z.enum(['code-router', 'file-router']),
|
|
17
|
+
framework: z.string(),
|
|
18
|
+
}),
|
|
19
|
+
)
|
|
20
|
+
.optional(),
|
|
21
|
+
'add-ons': z
|
|
22
|
+
.array(
|
|
23
|
+
z.object({
|
|
24
|
+
name: z.string(),
|
|
25
|
+
description: z.string(),
|
|
26
|
+
url: z.string(),
|
|
27
|
+
modes: z.array(z.enum(['code-router', 'file-router'])),
|
|
28
|
+
framework: z.string(),
|
|
29
|
+
}),
|
|
30
|
+
)
|
|
31
|
+
.optional(),
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
export type Registry = z.infer<typeof registrySchema>
|
|
23
35
|
|
|
24
36
|
function absolutizeUrl(originalUrl: string, relativeUrl: string) {
|
|
25
37
|
if (relativeUrl.startsWith('http') || relativeUrl.startsWith('https')) {
|
|
@@ -34,23 +46,25 @@ export async function getRawRegistry(
|
|
|
34
46
|
): Promise<Registry | undefined> {
|
|
35
47
|
const regUrl = registryUrl || process.env.CTA_REGISTRY
|
|
36
48
|
if (regUrl) {
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
49
|
+
const url = handleSpecialURL(regUrl)
|
|
50
|
+
const registry = (await fetch(url).then((res) => res.json())) as Registry
|
|
51
|
+
const parsedRegistry = registrySchema.parse(registry)
|
|
52
|
+
for (const addOn of parsedRegistry['add-ons'] || []) {
|
|
53
|
+
addOn.url = absolutizeUrl(url, addOn.url)
|
|
40
54
|
}
|
|
41
|
-
for (const starter of
|
|
42
|
-
starter.url = absolutizeUrl(
|
|
55
|
+
for (const starter of parsedRegistry.starters || []) {
|
|
56
|
+
starter.url = absolutizeUrl(url, starter.url)
|
|
43
57
|
if (starter.banner) {
|
|
44
|
-
starter.banner = absolutizeUrl(
|
|
58
|
+
starter.banner = absolutizeUrl(url, starter.banner)
|
|
45
59
|
}
|
|
46
60
|
}
|
|
47
|
-
return
|
|
61
|
+
return parsedRegistry
|
|
48
62
|
}
|
|
49
63
|
}
|
|
50
64
|
|
|
51
65
|
async function getAddOns(registry: Registry): Promise<Array<AddOn>> {
|
|
52
66
|
const addOns: Array<AddOn> = []
|
|
53
|
-
for (const addOnInfo of registry['add-ons']) {
|
|
67
|
+
for (const addOnInfo of registry['add-ons'] || []) {
|
|
54
68
|
const addOn = await loadRemoteAddOn(addOnInfo.url)
|
|
55
69
|
addOns.push(addOn)
|
|
56
70
|
}
|
|
@@ -66,7 +80,7 @@ export async function getRegistryAddOns(
|
|
|
66
80
|
|
|
67
81
|
async function getStarters(registry: Registry): Promise<Array<Starter>> {
|
|
68
82
|
const starters: Array<Starter> = []
|
|
69
|
-
for (const starterInfo of registry.starters) {
|
|
83
|
+
for (const starterInfo of registry.starters || []) {
|
|
70
84
|
const starter = await loadStarter(starterInfo.url)
|
|
71
85
|
starters.push(starter)
|
|
72
86
|
}
|
package/src/utils.ts
CHANGED
|
@@ -25,3 +25,18 @@ export function formatCommand({
|
|
|
25
25
|
}) {
|
|
26
26
|
return `${command} ${args.join(' ')}`.trim()
|
|
27
27
|
}
|
|
28
|
+
|
|
29
|
+
// Turn GitHub URLs into raw URLs
|
|
30
|
+
export function handleSpecialURL(url: string) {
|
|
31
|
+
if (url.startsWith('https://github.com/') && url.includes('blob')) {
|
|
32
|
+
return url
|
|
33
|
+
.replace('https://github.com/', 'https://raw.githubusercontent.com/')
|
|
34
|
+
.replace('/blob/', '/refs/heads/')
|
|
35
|
+
}
|
|
36
|
+
if (url.startsWith('https://github.com/') && url.includes('tree')) {
|
|
37
|
+
return url
|
|
38
|
+
.replace('https://github.com/', 'https://raw.githubusercontent.com/')
|
|
39
|
+
.replace('/tree/', '/refs/heads/')
|
|
40
|
+
}
|
|
41
|
+
return url
|
|
42
|
+
}
|
package/tests/utils.test.ts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { describe, expect, it } from 'vitest'
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
formatCommand,
|
|
5
|
+
handleSpecialURL,
|
|
6
|
+
jsSafeName,
|
|
7
|
+
sortObject,
|
|
8
|
+
} from '../src/utils.js'
|
|
4
9
|
|
|
5
10
|
describe('formatCommand', () => {
|
|
6
11
|
it('should format a command', () => {
|
|
@@ -21,3 +26,23 @@ describe('sortObject', () => {
|
|
|
21
26
|
expect(sortObject({ b: 'b', a: 'a' })).toEqual({ a: 'a', b: 'b' })
|
|
22
27
|
})
|
|
23
28
|
})
|
|
29
|
+
|
|
30
|
+
describe('handleSpecialURL', () => {
|
|
31
|
+
it('should handle special URLs', () => {
|
|
32
|
+
expect(
|
|
33
|
+
handleSpecialURL(
|
|
34
|
+
'https://github.com/TanStack/create-tsrouter-app/blob/main/examples/react-cra/registry.json',
|
|
35
|
+
),
|
|
36
|
+
).toEqual(
|
|
37
|
+
'https://raw.githubusercontent.com/TanStack/create-tsrouter-app/refs/heads/main/examples/react-cra/registry.json',
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
expect(
|
|
41
|
+
handleSpecialURL(
|
|
42
|
+
'https://github.com/TanStack/create-tsrouter-app/tree/alpha/packages/cta-cli/tsconfig.json',
|
|
43
|
+
),
|
|
44
|
+
).toEqual(
|
|
45
|
+
'https://raw.githubusercontent.com/TanStack/create-tsrouter-app/refs/heads/alpha/packages/cta-cli/tsconfig.json',
|
|
46
|
+
)
|
|
47
|
+
})
|
|
48
|
+
})
|