@ossy/cli 1.32.0 → 1.32.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/package.json +4 -4
- package/src/app/cli.js +5 -63
- package/src/app/load-config.js +34 -90
- package/src/app/publish.js +2 -27
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ossy/cli",
|
|
3
|
-
"version": "1.32.
|
|
3
|
+
"version": "1.32.2",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/ossy-se/packages.git"
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"@babel/parser": "^7.28.6",
|
|
23
|
-
"@ossy/app": "^1.32.
|
|
24
|
-
"@ossy/sdk": "^1.32.
|
|
23
|
+
"@ossy/app": "^1.32.2",
|
|
24
|
+
"@ossy/sdk": "^1.32.2",
|
|
25
25
|
"arg": "^5.0.2",
|
|
26
26
|
"glob": "^13.0.6"
|
|
27
27
|
},
|
|
@@ -33,5 +33,5 @@
|
|
|
33
33
|
"/src",
|
|
34
34
|
"README.md"
|
|
35
35
|
],
|
|
36
|
-
"gitHead": "
|
|
36
|
+
"gitHead": "5c17e379298f7027f1dbdcf064a4aff69d1497d5"
|
|
37
37
|
}
|
package/src/app/cli.js
CHANGED
|
@@ -6,10 +6,6 @@ import { logInfo, logError } from '../log.js'
|
|
|
6
6
|
import { resolveAppConfigPath } from '../resolve-app-config-path.js'
|
|
7
7
|
import { getAuth } from '../state.js'
|
|
8
8
|
import { init } from '../init/cli.js'
|
|
9
|
-
import {
|
|
10
|
-
postResourceTemplates,
|
|
11
|
-
resolveApiBaseUrlForUpload,
|
|
12
|
-
} from './upload-resource-templates.js'
|
|
13
9
|
import { publish } from './publish.js'
|
|
14
10
|
|
|
15
11
|
const resolveConfigImport = (filePath) =>
|
|
@@ -27,7 +23,6 @@ const upload = (options) => {
|
|
|
27
23
|
}, { argv: options })
|
|
28
24
|
|
|
29
25
|
const token = getAuth({ flag: parsedArgs['--authentication'] })
|
|
30
|
-
const apiUrlFlag = parsedArgs['--api-url']
|
|
31
26
|
|
|
32
27
|
if (!token) {
|
|
33
28
|
logError({
|
|
@@ -50,50 +45,11 @@ const upload = (options) => {
|
|
|
50
45
|
process.exit(1)
|
|
51
46
|
}
|
|
52
47
|
|
|
53
|
-
logInfo({
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
const workspaceId = config?.workspaceId
|
|
59
|
-
const resourceTemplates = config?.resourceTemplates
|
|
60
|
-
|
|
61
|
-
if (!workspaceId) {
|
|
62
|
-
logError({ message: '[@ossy/cli] No workspaceId in config' })
|
|
63
|
-
process.exit(1)
|
|
64
|
-
}
|
|
65
|
-
if (!resourceTemplates) {
|
|
66
|
-
logError({ message: '[@ossy/cli] No resourceTemplates in config' })
|
|
67
|
-
process.exit(1)
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const apiBaseUrl = resolveApiBaseUrlForUpload({
|
|
71
|
-
flag: apiUrlFlag,
|
|
72
|
-
envVar: process.env.OSSY_API_URL,
|
|
73
|
-
configApiUrl: config?.apiUrl,
|
|
74
|
-
})
|
|
75
|
-
|
|
76
|
-
logInfo({ message: '[@ossy/cli] Uploading resource templates...' })
|
|
77
|
-
|
|
78
|
-
return postResourceTemplates({
|
|
79
|
-
apiBaseUrl,
|
|
80
|
-
token,
|
|
81
|
-
workspaceId,
|
|
82
|
-
resourceTemplates,
|
|
83
|
-
})
|
|
84
|
-
.then((response) => {
|
|
85
|
-
if (!response.ok) throw new Error(`Upload failed: ${response.status}`)
|
|
86
|
-
logInfo({ message: '[@ossy/cli] Done' })
|
|
87
|
-
})
|
|
88
|
-
.catch((error) => {
|
|
89
|
-
logError({ message: '[@ossy/cli] Error', error })
|
|
90
|
-
process.exit(1)
|
|
91
|
-
})
|
|
92
|
-
})
|
|
93
|
-
.catch((error) => {
|
|
94
|
-
logError({ message: '[@ossy/cli] Error', error })
|
|
95
|
-
process.exit(1)
|
|
96
|
-
})
|
|
48
|
+
logInfo({
|
|
49
|
+
message:
|
|
50
|
+
'[@ossy/cli] Resource templates are now defined in *.resource.js package files and are ' +
|
|
51
|
+
'automatically discovered at build time. Use `ossy app publish` to deploy.',
|
|
52
|
+
})
|
|
97
53
|
}
|
|
98
54
|
|
|
99
55
|
const validate = (options) => {
|
|
@@ -121,23 +77,9 @@ const validate = (options) => {
|
|
|
121
77
|
.then((module) => {
|
|
122
78
|
const config = module?.default ?? module
|
|
123
79
|
const workspaceId = config?.workspaceId
|
|
124
|
-
const resourceTemplates = config?.resourceTemplates
|
|
125
80
|
|
|
126
81
|
const errors = []
|
|
127
82
|
if (!workspaceId) errors.push('Missing workspaceId')
|
|
128
|
-
if (!resourceTemplates) {
|
|
129
|
-
errors.push('Missing resourceTemplates')
|
|
130
|
-
} else if (!Array.isArray(resourceTemplates)) {
|
|
131
|
-
errors.push('resourceTemplates must be an array')
|
|
132
|
-
} else {
|
|
133
|
-
resourceTemplates.forEach((t, i) => {
|
|
134
|
-
if (!t.id) errors.push(`Template ${i}: missing id`)
|
|
135
|
-
if (!t.name) errors.push(`Template ${i}: missing name`)
|
|
136
|
-
if (!t.fields || !Array.isArray(t.fields)) {
|
|
137
|
-
errors.push(`Template ${i}: fields must be an array`)
|
|
138
|
-
}
|
|
139
|
-
})
|
|
140
|
-
}
|
|
141
83
|
|
|
142
84
|
if (errors.length > 0) {
|
|
143
85
|
console.error('[@ossy/cli] Validation failed:')
|
package/src/app/load-config.js
CHANGED
|
@@ -2,96 +2,28 @@ import { readFileSync } from 'fs'
|
|
|
2
2
|
import { resolve } from 'path'
|
|
3
3
|
import { parse } from '@babel/parser'
|
|
4
4
|
|
|
5
|
-
/** @returns {unknown | undefined} `undefined` if the AST cannot be reduced to JSON-like data */
|
|
6
|
-
function astNodeToLiteralValue (node) {
|
|
7
|
-
if (!node) return undefined
|
|
8
|
-
switch (node.type) {
|
|
9
|
-
case 'StringLiteral':
|
|
10
|
-
case 'BooleanLiteral':
|
|
11
|
-
return node.value
|
|
12
|
-
case 'NumericLiteral':
|
|
13
|
-
return node.value
|
|
14
|
-
case 'NullLiteral':
|
|
15
|
-
return null
|
|
16
|
-
case 'UnaryExpression':
|
|
17
|
-
if (node.operator === '-' && node.argument?.type === 'NumericLiteral') {
|
|
18
|
-
return -node.argument.value
|
|
19
|
-
}
|
|
20
|
-
return undefined
|
|
21
|
-
case 'ObjectExpression': {
|
|
22
|
-
const o = Object.create(null)
|
|
23
|
-
for (const p of node.properties) {
|
|
24
|
-
if (p.type !== 'ObjectProperty' || p.computed) return undefined
|
|
25
|
-
if (p.shorthand) return undefined
|
|
26
|
-
const key =
|
|
27
|
-
p.key.type === 'Identifier'
|
|
28
|
-
? p.key.name
|
|
29
|
-
: p.key.type === 'StringLiteral'
|
|
30
|
-
? p.key.value
|
|
31
|
-
: undefined
|
|
32
|
-
if (key === undefined) return undefined
|
|
33
|
-
const v = astNodeToLiteralValue(p.value)
|
|
34
|
-
if (v === undefined) return undefined
|
|
35
|
-
o[key] = v
|
|
36
|
-
}
|
|
37
|
-
return o
|
|
38
|
-
}
|
|
39
|
-
case 'ArrayExpression': {
|
|
40
|
-
const arr = []
|
|
41
|
-
for (const el of node.elements) {
|
|
42
|
-
if (el === null) {
|
|
43
|
-
arr.push(null)
|
|
44
|
-
continue
|
|
45
|
-
}
|
|
46
|
-
if (el.type === 'SpreadElement') return undefined
|
|
47
|
-
const v = astNodeToLiteralValue(el)
|
|
48
|
-
if (v === undefined) return undefined
|
|
49
|
-
arr.push(v)
|
|
50
|
-
}
|
|
51
|
-
return arr
|
|
52
|
-
}
|
|
53
|
-
default:
|
|
54
|
-
return undefined
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
5
|
/**
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
* @param {string} source
|
|
63
|
-
* @returns {unknown[] | undefined}
|
|
6
|
+
* Converts a Babel AST value node to a plain JS value.
|
|
7
|
+
* Handles strings, numbers, booleans, null, arrays, and plain objects.
|
|
64
8
|
*/
|
|
65
|
-
function
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
for (const stmt of ast.program.body) {
|
|
74
|
-
if (stmt.type !== 'ExportDefaultDeclaration') continue
|
|
75
|
-
const decl = stmt.declaration
|
|
76
|
-
if (decl.type === 'ObjectExpression') {
|
|
77
|
-
obj = decl
|
|
78
|
-
break
|
|
79
|
-
}
|
|
9
|
+
function astToValue (node) {
|
|
10
|
+
if (!node) return undefined
|
|
11
|
+
if (node.type === 'StringLiteral') return node.value
|
|
12
|
+
if (node.type === 'NumericLiteral') return node.value
|
|
13
|
+
if (node.type === 'BooleanLiteral') return node.value
|
|
14
|
+
if (node.type === 'NullLiteral') return null
|
|
15
|
+
if (node.type === 'ArrayExpression') {
|
|
16
|
+
return node.elements.map(el => el ? astToValue(el) : null)
|
|
80
17
|
}
|
|
81
|
-
if (
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
: null
|
|
91
|
-
if (key !== 'resourceTemplates') continue
|
|
92
|
-
if (prop.value.type !== 'ArrayExpression') return undefined
|
|
93
|
-
const v = astNodeToLiteralValue(prop.value)
|
|
94
|
-
return Array.isArray(v) ? v : undefined
|
|
18
|
+
if (node.type === 'ObjectExpression') {
|
|
19
|
+
const obj = {}
|
|
20
|
+
for (const prop of node.properties) {
|
|
21
|
+
if (prop.type === 'ObjectProperty') {
|
|
22
|
+
const key = prop.key.name ?? prop.key.value
|
|
23
|
+
obj[key] = astToValue(prop.value)
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return obj
|
|
95
27
|
}
|
|
96
28
|
return undefined
|
|
97
29
|
}
|
|
@@ -101,7 +33,7 @@ function extractResourceTemplatesFromSource (source) {
|
|
|
101
33
|
* Avoids resolving imports such as `@ossy/themes` in CI.
|
|
102
34
|
*
|
|
103
35
|
* @param {string} configPath Absolute or cwd-relative path to `src/config.js`
|
|
104
|
-
* @returns {{ workspaceId?: string, apiUrl?: string, domain?: string, resourceTemplates?:
|
|
36
|
+
* @returns {{ workspaceId?: string, apiUrl?: string, domain?: string, resourceTemplates?: object[] }}
|
|
105
37
|
*/
|
|
106
38
|
export function readAppConfig (configPath) {
|
|
107
39
|
const abs = resolve(configPath)
|
|
@@ -114,9 +46,21 @@ export function readAppConfig (configPath) {
|
|
|
114
46
|
|
|
115
47
|
let resourceTemplates
|
|
116
48
|
try {
|
|
117
|
-
|
|
49
|
+
const ast = parse(source, { sourceType: 'module' })
|
|
50
|
+
for (const node of ast.program.body) {
|
|
51
|
+
if (node.type !== 'ExportDefaultDeclaration') continue
|
|
52
|
+
const obj = node.declaration
|
|
53
|
+
if (obj.type !== 'ObjectExpression') continue
|
|
54
|
+
for (const prop of obj.properties) {
|
|
55
|
+
if (prop.type !== 'ObjectProperty') continue
|
|
56
|
+
const key = prop.key.name ?? prop.key.value
|
|
57
|
+
if (key === 'resourceTemplates' && prop.value.type === 'ArrayExpression') {
|
|
58
|
+
resourceTemplates = astToValue(prop.value)
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
118
62
|
} catch {
|
|
119
|
-
resourceTemplates
|
|
63
|
+
// Ignore parse errors — resourceTemplates stays undefined
|
|
120
64
|
}
|
|
121
65
|
|
|
122
66
|
return {
|
package/src/app/publish.js
CHANGED
|
@@ -8,7 +8,6 @@ import { getAuth } from '../state.js'
|
|
|
8
8
|
import { walk } from '../upload-dir/cli.js'
|
|
9
9
|
import { prepareFileUpload, uploadFileToUrl } from '../file.js'
|
|
10
10
|
import {
|
|
11
|
-
postResourceTemplates,
|
|
12
11
|
requireAppAuthentication,
|
|
13
12
|
resolveApiBaseUrlForUpload,
|
|
14
13
|
} from './upload-resource-templates.js'
|
|
@@ -28,7 +27,6 @@ export async function publish (options) {
|
|
|
28
27
|
'-c': '--config',
|
|
29
28
|
'--build-dir': String,
|
|
30
29
|
'--build-dest': String,
|
|
31
|
-
'--skip-resource-templates': Boolean,
|
|
32
30
|
'--api-url': String,
|
|
33
31
|
}, { argv: options })
|
|
34
32
|
|
|
@@ -45,7 +43,7 @@ export async function publish (options) {
|
|
|
45
43
|
}
|
|
46
44
|
|
|
47
45
|
const config = readAppConfig(configPath)
|
|
48
|
-
const { workspaceId, apiUrl: configApiUrl, domain
|
|
46
|
+
const { workspaceId, apiUrl: configApiUrl, domain } = config
|
|
49
47
|
|
|
50
48
|
if (!workspaceId) {
|
|
51
49
|
logError({ message: '[@ossy/cli] app publish: no workspaceId in config' })
|
|
@@ -69,30 +67,7 @@ export async function publish (options) {
|
|
|
69
67
|
process.exit(1)
|
|
70
68
|
}
|
|
71
69
|
|
|
72
|
-
// Step 1: upload
|
|
73
|
-
if (!parsedArgs['--skip-resource-templates']) {
|
|
74
|
-
if (Array.isArray(resourceTemplates) && resourceTemplates.length > 0) {
|
|
75
|
-
logInfo({ message: '[@ossy/cli] app publish: uploading resource templates…' })
|
|
76
|
-
const res = await postResourceTemplates({
|
|
77
|
-
apiBaseUrl,
|
|
78
|
-
token: authToken,
|
|
79
|
-
workspaceId,
|
|
80
|
-
resourceTemplates,
|
|
81
|
-
})
|
|
82
|
-
if (!res.ok) {
|
|
83
|
-
const text = await res.text().catch(() => '')
|
|
84
|
-
logError({
|
|
85
|
-
message: `[@ossy/cli] app publish: resource template upload failed: HTTP ${res.status}${text ? ` — ${text.slice(0, 200)}` : ''}`,
|
|
86
|
-
})
|
|
87
|
-
process.exit(1)
|
|
88
|
-
}
|
|
89
|
-
logInfo({ message: '[@ossy/cli] app publish: resource templates uploaded' })
|
|
90
|
-
} else {
|
|
91
|
-
logInfo({ message: '[@ossy/cli] app publish: no resource templates in config, skipping' })
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// Step 2: upload build/ to CMS
|
|
70
|
+
// Step 1: upload build/ to CMS
|
|
96
71
|
const packageRoot = path.join(path.dirname(configPath), '..')
|
|
97
72
|
const buildDir = parsedArgs['--build-dir']
|
|
98
73
|
? path.resolve(parsedArgs['--build-dir'])
|