@conduction/nextcloud-vue 2.2.0-vue3.13 → 2.2.0-vue3.14
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 +2 -1
- package/scripts/.jsdoc-baselines.json +254 -0
- package/scripts/build-validators.js +174 -0
- package/scripts/check-css-entry.js +118 -0
- package/scripts/check-docs.js +724 -0
- package/scripts/check-integration-build.js +180 -0
- package/scripts/check-integration-parity.js +540 -0
- package/scripts/check-jsdoc.js +230 -0
- package/scripts/check-peer-consistency.js +161 -0
- package/scripts/generate-nl-icons.mjs +98 -0
- package/scripts/precommit-regenerate-features.sh +33 -0
- package/scripts/precommit-regenerate-partials.sh +68 -0
- package/scripts/sync-l10n-ellipsis.js +46 -0
- package/scripts/update-fleet-manifest-fixtures.js +116 -0
- package/scripts/vue3-compile-sweep.cjs +77 -0
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Integration-leaf template-compile gate (Phase K / K1).
|
|
5
|
+
*
|
|
6
|
+
* THE NEAR-MISS THIS GUARDS AGAINST
|
|
7
|
+
* ---------------------------------
|
|
8
|
+
* During the pluggable-integration-registry rollout (ADR-019) a
|
|
9
|
+
* template-side ES2020 optional-chain slipped into
|
|
10
|
+
* `src/integrations/builtin/contacts/CnContactsCard.vue` — an
|
|
11
|
+
* `obj?.field` expression *inside the `<template>` block*. jest passed
|
|
12
|
+
* (its vue-jest transform tolerates modern syntax), but `npm run build`
|
|
13
|
+
* broke: Vue 2's render-function transpiler
|
|
14
|
+
* (vue-template-compiler → vue-template-es2015-compiler → buble) does
|
|
15
|
+
* NOT understand optional chaining (`?.`) or nullish coalescing (`??`)
|
|
16
|
+
* in template expressions. jest never traverses buble, so the failure
|
|
17
|
+
* only surfaced at build time.
|
|
18
|
+
*
|
|
19
|
+
* WHAT THIS DOES
|
|
20
|
+
* --------------
|
|
21
|
+
* Compiles every integration SFC's `<template>` block through the same
|
|
22
|
+
* `vue-template-compiler` that `rollup-plugin-vue` uses at build time,
|
|
23
|
+
* then runs the generated render function through buble — exactly the
|
|
24
|
+
* path that rejects template-side ES2020. A failure here is ATTRIBUTED
|
|
25
|
+
* to the offending integration file with a precise message, instead of
|
|
26
|
+
* surfacing as an opaque rollup error deep in `npm run build`.
|
|
27
|
+
*
|
|
28
|
+
* This is the fast-feedback companion to the full `npm run build`
|
|
29
|
+
* step in `.github/workflows/code-quality.yml`: the build remains the
|
|
30
|
+
* authoritative gate, but this script (wired into `npm run lint` peers
|
|
31
|
+
* via `check:integration-build` and the pre-commit hook) fails in
|
|
32
|
+
* seconds and points at the exact `.vue` file + line class.
|
|
33
|
+
*
|
|
34
|
+
* Scoped to `src/integrations/builtin/**.vue` to stay aligned with the
|
|
35
|
+
* K2 ESLint rule and avoid fleet-wide churn.
|
|
36
|
+
*
|
|
37
|
+
* Run via `npm run check:integration-build`.
|
|
38
|
+
*
|
|
39
|
+
* Exit codes:
|
|
40
|
+
* 0 — every integration SFC template compiles through buble
|
|
41
|
+
* 1 — at least one template uses syntax buble rejects (e.g. `?.`/`??`)
|
|
42
|
+
*/
|
|
43
|
+
|
|
44
|
+
'use strict'
|
|
45
|
+
|
|
46
|
+
const fs = require('fs')
|
|
47
|
+
const path = require('path')
|
|
48
|
+
|
|
49
|
+
const INTEGRATIONS_DIR = path.resolve(__dirname, '../src/integrations/builtin')
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Recursively collect every `*.vue` file under a directory.
|
|
53
|
+
*
|
|
54
|
+
* @param {string} dir Directory to walk.
|
|
55
|
+
*
|
|
56
|
+
* @return {string[]} Absolute paths to `.vue` files.
|
|
57
|
+
*/
|
|
58
|
+
function collectVueFiles(dir) {
|
|
59
|
+
const out = []
|
|
60
|
+
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
61
|
+
const full = path.join(dir, entry.name)
|
|
62
|
+
if (entry.isDirectory()) {
|
|
63
|
+
out.push(...collectVueFiles(full))
|
|
64
|
+
} else if (entry.isFile() && entry.name.endsWith('.vue')) {
|
|
65
|
+
out.push(full)
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return out
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Print the result to stdout/stderr.
|
|
73
|
+
*
|
|
74
|
+
* @param {Array<{file: string, message: string}>} list Failures.
|
|
75
|
+
*
|
|
76
|
+
* @return {void}
|
|
77
|
+
*/
|
|
78
|
+
function report(list) {
|
|
79
|
+
if (list.length === 0) {
|
|
80
|
+
// eslint-disable-next-line no-console
|
|
81
|
+
console.log('✓ integration build: every integration SFC template compiles through buble (no template-side ES2020)')
|
|
82
|
+
return
|
|
83
|
+
}
|
|
84
|
+
// eslint-disable-next-line no-console
|
|
85
|
+
console.error('✗ integration template-compile gate failed:')
|
|
86
|
+
for (const f of list) {
|
|
87
|
+
// eslint-disable-next-line no-console
|
|
88
|
+
console.error(` - ${path.relative(process.cwd(), f.file)}: ${f.message}`)
|
|
89
|
+
}
|
|
90
|
+
// eslint-disable-next-line no-console
|
|
91
|
+
console.error('\nVue 2 template expressions are transpiled by buble, which does NOT')
|
|
92
|
+
// eslint-disable-next-line no-console
|
|
93
|
+
console.error('support optional chaining (?.) or nullish coalescing (??) inside a')
|
|
94
|
+
// eslint-disable-next-line no-console
|
|
95
|
+
console.error('<template> block. Move the expression into a computed/method, or use')
|
|
96
|
+
// eslint-disable-next-line no-console
|
|
97
|
+
console.error('an explicit (a && a.b) / (a == null ? d : a) form in the template.')
|
|
98
|
+
// eslint-disable-next-line no-console
|
|
99
|
+
console.error('(See K1/K2 of the integration-hardening change; ADR-019.)')
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
let vueCompiler
|
|
103
|
+
let transpileToFunctions
|
|
104
|
+
try {
|
|
105
|
+
// eslint-disable-next-line global-require, import/no-extraneous-dependencies
|
|
106
|
+
vueCompiler = require('vue-template-compiler')
|
|
107
|
+
// vue-template-compiler ships the es2015 (buble) transpiler that
|
|
108
|
+
// rollup-plugin-vue uses to turn the compiled render string into a
|
|
109
|
+
// function. This is the exact stage that rejects template ES2020.
|
|
110
|
+
// eslint-disable-next-line global-require, import/no-extraneous-dependencies
|
|
111
|
+
transpileToFunctions = require('vue-template-es2015-compiler')
|
|
112
|
+
} catch (e) {
|
|
113
|
+
// In a toolchain without these deps installed (e.g. a docs-only CI
|
|
114
|
+
// lane), fall back to a static scan of `<template>` blocks for `?.`
|
|
115
|
+
// and `??`. Coarser, but never silently passes.
|
|
116
|
+
staticFallback()
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (vueCompiler && transpileToFunctions) {
|
|
120
|
+
compileEach()
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Authoritative path: compile each SFC template through
|
|
125
|
+
* vue-template-compiler + buble.
|
|
126
|
+
*
|
|
127
|
+
* @return {void}
|
|
128
|
+
*/
|
|
129
|
+
function compileEach() {
|
|
130
|
+
const failures = []
|
|
131
|
+
for (const file of collectVueFiles(INTEGRATIONS_DIR)) {
|
|
132
|
+
const sfc = fs.readFileSync(file, 'utf8')
|
|
133
|
+
const parsed = vueCompiler.parseComponent(sfc)
|
|
134
|
+
const template = parsed.template && parsed.template.content
|
|
135
|
+
if (!template || template.trim() === '') {
|
|
136
|
+
continue
|
|
137
|
+
}
|
|
138
|
+
const compiled = vueCompiler.compile(template)
|
|
139
|
+
if (compiled.errors && compiled.errors.length > 0) {
|
|
140
|
+
failures.push({ file, message: compiled.errors.join('; ') })
|
|
141
|
+
continue
|
|
142
|
+
}
|
|
143
|
+
// The render fn string is what rollup-plugin-vue feeds to buble.
|
|
144
|
+
const code = `var render = function(){${compiled.render}}\n`
|
|
145
|
+
+ `var staticRenderFns = [${(compiled.staticRenderFns || []).map(fn => `function(){${fn}}`).join(',')}]`
|
|
146
|
+
try {
|
|
147
|
+
transpileToFunctions(code, { transforms: { stripWithFunctional: false } })
|
|
148
|
+
} catch (err) {
|
|
149
|
+
failures.push({ file, message: `buble rejected template render fn (likely template-side ES2020 ?./??): ${err.message}` })
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
report(failures)
|
|
153
|
+
process.exit(failures.length === 0 ? 0 : 1)
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Fallback path: static scan of `<template>` blocks for `?.` / `??`.
|
|
158
|
+
*
|
|
159
|
+
* @return {void}
|
|
160
|
+
*/
|
|
161
|
+
function staticFallback() {
|
|
162
|
+
const failures = []
|
|
163
|
+
for (const file of collectVueFiles(INTEGRATIONS_DIR)) {
|
|
164
|
+
const sfc = fs.readFileSync(file, 'utf8')
|
|
165
|
+
const match = sfc.match(/<template[^>]*>([\s\S]*?)<\/template>/i)
|
|
166
|
+
if (!match) {
|
|
167
|
+
continue
|
|
168
|
+
}
|
|
169
|
+
const tpl = match[1]
|
|
170
|
+
// Optional chaining: `?.` not part of a ternary. Nullish: `??`.
|
|
171
|
+
if (/\?\./.test(tpl)) {
|
|
172
|
+
failures.push({ file, message: 'optional chaining (?.) found in <template> (buble rejects it)' })
|
|
173
|
+
}
|
|
174
|
+
if (/\?\?/.test(tpl)) {
|
|
175
|
+
failures.push({ file, message: 'nullish coalescing (??) found in <template> (buble rejects it)' })
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
report(failures)
|
|
179
|
+
process.exit(failures.length === 0 ? 0 : 1)
|
|
180
|
+
}
|