@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ossy/cli",
3
- "version": "1.32.0",
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.0",
24
- "@ossy/sdk": "^1.32.0",
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": "08b323d32d21600ba9519ad3f73fd5738556a68f"
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({ message: '[@ossy/cli] Reading config...' })
54
-
55
- return resolveConfigImport(filePath)
56
- .then((module) => {
57
- const config = module?.default ?? module
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:')
@@ -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
- * Reads `resourceTemplates` from `export default { ... }` when it is a literal array
60
- * (no imports, calls, or templates). Matches typical Ossy website configs.
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 extractResourceTemplatesFromSource (source) {
66
- const ast = parse(source, {
67
- sourceType: 'module',
68
- allowAwaitOutsideFunction: true,
69
- errorRecovery: false,
70
- })
71
-
72
- let obj = null
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 (!obj) return undefined
82
-
83
- for (const prop of obj.properties) {
84
- if (prop.type !== 'ObjectProperty' || prop.computed) continue
85
- const key =
86
- prop.key.type === 'Identifier'
87
- ? prop.key.name
88
- : prop.key.type === 'StringLiteral'
89
- ? prop.key.value
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?: unknown[] }}
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
- resourceTemplates = extractResourceTemplatesFromSource(source)
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 = undefined
63
+ // Ignore parse errors — resourceTemplates stays undefined
120
64
  }
121
65
 
122
66
  return {
@@ -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, resourceTemplates } = config
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 resource templates
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'])