@cassida/core 0.1.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/LICENSE +21 -0
- package/dist/index.d.ts +195 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +141 -0
- package/dist/index.js.map +1 -0
- package/package.json +52 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 FSS contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import { canonicalModifiers, canonicalSpec, type CanonicalSpec, type GeneratedSpecMap } from '@cassida/compiler';
|
|
2
|
+
import type * as CSS from 'csstype';
|
|
3
|
+
/**
|
|
4
|
+
* Method shape derived from the canonical (hand-crafted) style spec.
|
|
5
|
+
*
|
|
6
|
+
* Each method's argument signature is extracted from the spec's typed
|
|
7
|
+
* `format` function via `Parameters<...>`, so adding a property to the
|
|
8
|
+
* spec automatically adds a typed method here.
|
|
9
|
+
*/
|
|
10
|
+
type ChainMethodsFromSpec<S> = {
|
|
11
|
+
[K in keyof S]: S[K] extends {
|
|
12
|
+
format: (...args: infer A) => string;
|
|
13
|
+
} ? (...args: A) => CassChain : never;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Method shape for the auto-generated mdn-data spec set, with keys
|
|
17
|
+
* already covered by the hand-crafted canonical spec excluded.
|
|
18
|
+
*
|
|
19
|
+
* Why exclude: TypeScript's method-intersection forms an overloaded
|
|
20
|
+
* call signature whose accepted args is the *union* of each branch's
|
|
21
|
+
* args. If we declared `color` in BOTH a typed (csstype) and a
|
|
22
|
+
* permissive (string | number) form, the intersection would let
|
|
23
|
+
* `cas().color(123)` typecheck — loosening the curated typing. By
|
|
24
|
+
* dropping overlapping keys, we let hand-crafted entries reign for
|
|
25
|
+
* their domain and the generated set fills only the genuine gaps.
|
|
26
|
+
*/
|
|
27
|
+
type ChainMethodsFromGenerated<S, EXCLUDE extends string | number | symbol> = {
|
|
28
|
+
[K in keyof S as K extends EXCLUDE ? never : K]: (value: string | number) => CassChain;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Method set generated from the default canonical spec.
|
|
32
|
+
*/
|
|
33
|
+
export type DefaultChainMethods = ChainMethodsFromSpec<CanonicalSpec>;
|
|
34
|
+
/**
|
|
35
|
+
* Method set generated from the mdn-data-derived spec table. Includes
|
|
36
|
+
* every standard CSS property (~460 entries, vendor and non-standard
|
|
37
|
+
* stripped). Hand-crafted methods of the same name override these via
|
|
38
|
+
* the CassChain intersection so curated typing wins.
|
|
39
|
+
*/
|
|
40
|
+
export type GeneratedChainMethods = ChainMethodsFromGenerated<GeneratedSpecMap, keyof CanonicalSpec>;
|
|
41
|
+
/**
|
|
42
|
+
* Callback signature for modifier methods. The argument is a fresh
|
|
43
|
+
* scoped chain whose ops accumulate into the modifier's sub-scope.
|
|
44
|
+
* Returning the chain is conventional but not required (return value
|
|
45
|
+
* is ignored).
|
|
46
|
+
*/
|
|
47
|
+
export type ScopedCallback = (chain: CassChain) => CassChain | unknown;
|
|
48
|
+
/**
|
|
49
|
+
* Modifier methods are zero-arg shorthands for common scopes
|
|
50
|
+
* (`hover`, `focus`, `before`, `darkMode`, ...) plus two arg-taking
|
|
51
|
+
* generics (`media(query, cb)` and `on(selector, cb)`).
|
|
52
|
+
*
|
|
53
|
+
* Inside the callback, `c` is a fresh `CassChain` whose method calls
|
|
54
|
+
* push ops into the modifier's sub-scope. The outer chain wraps those
|
|
55
|
+
* inner ops in a `ScopedOp` and pushes it to its own ops list when the
|
|
56
|
+
* callback returns.
|
|
57
|
+
*/
|
|
58
|
+
type ZeroArgModifiers = {
|
|
59
|
+
[K in keyof typeof canonicalModifiers]: (cb: ScopedCallback) => CassChain;
|
|
60
|
+
};
|
|
61
|
+
export interface ChainModifiers extends ZeroArgModifiers {
|
|
62
|
+
on(selector: string, cb: ScopedCallback): CassChain;
|
|
63
|
+
media(query: string, cb: ScopedCallback): CassChain;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Escape-hatch chain method for properties outside FSS's safe surface
|
|
67
|
+
* (CSS shorthands, vendor prefixes, custom properties like `--brand-*`).
|
|
68
|
+
*
|
|
69
|
+
* Bypasses the registry, the shorthand-policy guard, and family
|
|
70
|
+
* tracking. Numeric values are NOT auto-unitized — the user is
|
|
71
|
+
* expected to pass a fully-formed CSS value string. Pairs naturally
|
|
72
|
+
* with `cas.unsafe(...)` for preset injection.
|
|
73
|
+
*
|
|
74
|
+
* `keyof CSS.PropertiesHyphen` provides IDE autocomplete for standard
|
|
75
|
+
* kebab-case property names; `(string & {})` preserves that
|
|
76
|
+
* autocomplete while still accepting any other string (for custom
|
|
77
|
+
* properties or browser experiments).
|
|
78
|
+
*/
|
|
79
|
+
export interface ChainSetMethod {
|
|
80
|
+
set(key: keyof CSS.PropertiesHyphen | (string & {}), value: string | number): CassChain;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Extension hook for downstream consumers.
|
|
84
|
+
*
|
|
85
|
+
* Users who add their own methods via `extendRegistry()` augment this
|
|
86
|
+
* interface in their own `.d.ts` to surface those methods on the chain.
|
|
87
|
+
*
|
|
88
|
+
* ```ts
|
|
89
|
+
* declare module '@cassida/core' {
|
|
90
|
+
* interface CassChainExtensions {
|
|
91
|
+
* brandColor(value: 'primary' | 'secondary'): CassChain;
|
|
92
|
+
* }
|
|
93
|
+
* }
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
export interface CassChainExtensions {
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Terminal members read by JSX spread. `style` is a `CSS.Properties`
|
|
100
|
+
* object (camelCase keys, csstype-typed values); `className` is filled
|
|
101
|
+
* in only by the build-time transform — at runtime this is undefined
|
|
102
|
+
* and the spread carries `style` instead.
|
|
103
|
+
*/
|
|
104
|
+
export interface CassChainTerminus {
|
|
105
|
+
readonly style: Readonly<CSS.Properties>;
|
|
106
|
+
readonly className?: string;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Full chain type: typed canonical style methods, modifiers, user
|
|
110
|
+
* extensions, and the JSX spread targets. The intersection means user
|
|
111
|
+
* augmentations of `CassChainExtensions` automatically propagate.
|
|
112
|
+
*/
|
|
113
|
+
/**
|
|
114
|
+
* Full chain type. Order of intersection matters: later items in the
|
|
115
|
+
* union DO NOT override earlier ones in TypeScript's intersection
|
|
116
|
+
* resolution, but properties of the same key WIDEN to a function
|
|
117
|
+
* signature compatible with both. We therefore put the *typed* hand-
|
|
118
|
+
* crafted methods first (so call sites see their precise signatures
|
|
119
|
+
* for autocomplete) and the permissive generated set after, so
|
|
120
|
+
* gap-filling methods exist but don't tighten / loosen the curated
|
|
121
|
+
* ones beyond what they already declare.
|
|
122
|
+
*/
|
|
123
|
+
export type CassChain = DefaultChainMethods & GeneratedChainMethods & ChainModifiers & ChainSetMethod & CassChainExtensions & CassChainTerminus;
|
|
124
|
+
/**
|
|
125
|
+
* CSS shorthands intentionally absent from the FSS canonical surface.
|
|
126
|
+
* Keys here are rejected from `SafePreset` (the `cas(preset)` arg type)
|
|
127
|
+
* — users wanting these values must explicitly route through
|
|
128
|
+
* `cas.unsafe(...)`, mirroring Rust's `unsafe` block contract.
|
|
129
|
+
*/
|
|
130
|
+
type BlacklistedSafeKeys = 'background' | 'font' | 'border' | 'flex' | 'grid' | 'all' | 'mask' | 'transition' | 'animation' | 'listStyle' | 'textDecoration' | 'placeItems' | 'placeContent' | 'placeSelf' | 'columns' | 'columnRule' | 'overflow' | 'gridArea' | 'gridTemplate';
|
|
131
|
+
/**
|
|
132
|
+
* Strictly-typed preset shape for the safe `cas(preset)` overload.
|
|
133
|
+
* csstype-typed CSS values, blacklisted shorthands removed at the
|
|
134
|
+
* type level so they don't autocomplete and can't be written.
|
|
135
|
+
*/
|
|
136
|
+
export type SafePreset = Partial<Omit<CSS.Properties, BlacklistedSafeKeys>>;
|
|
137
|
+
/**
|
|
138
|
+
* Permissive preset shape for `cas.unsafe(preset)`. Accepts any
|
|
139
|
+
* string key; intended for blacklisted shorthands, vendor-prefixed
|
|
140
|
+
* properties, and CSS custom properties (`--foo`). The contract is
|
|
141
|
+
* "you're past the safety guarantees, write raw CSS at your own
|
|
142
|
+
* discretion".
|
|
143
|
+
*/
|
|
144
|
+
export interface UnsafePreset {
|
|
145
|
+
readonly [key: string]: string | number | undefined;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Runtime `cas()` builder.
|
|
149
|
+
*
|
|
150
|
+
* - Production: build-time transform replaces `{...cas().a().b()}` with
|
|
151
|
+
* `{className: "fss-xxx"}` (and `style` for dynamics). This runtime
|
|
152
|
+
* is unreached for those sites.
|
|
153
|
+
* - Dev / dynamic chains: spread reads the enumerable `style` getter,
|
|
154
|
+
* chain materializes as inline style. Method handles are non-enumerable
|
|
155
|
+
* so they don't leak as React props.
|
|
156
|
+
*
|
|
157
|
+
* Overloads:
|
|
158
|
+
* - `cas()` — empty chain
|
|
159
|
+
* - `cas(preset)` — start from a typed preset (safe; blacklisted
|
|
160
|
+
* shorthands are excluded from the type and routed through
|
|
161
|
+
* `cas.unsafe`)
|
|
162
|
+
* - `cas.unsafe(preset)` — bypass the safety net; preset can include
|
|
163
|
+
* blacklisted shorthands, vendor properties, and CSS custom props
|
|
164
|
+
*/
|
|
165
|
+
export interface CassBuilder {
|
|
166
|
+
(): CassChain;
|
|
167
|
+
(preset: SafePreset): CassChain;
|
|
168
|
+
/**
|
|
169
|
+
* Escape hatch for properties outside FSS's safe surface (CSS
|
|
170
|
+
* shorthands like `background`, vendor-prefixed, custom `--foo`).
|
|
171
|
+
* Bypasses registry validation, shorthand-policy, and family
|
|
172
|
+
* tracking — the user takes responsibility for the resulting CSS.
|
|
173
|
+
*/
|
|
174
|
+
readonly unsafe: (preset: UnsafePreset) => CassChain;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Cassida's chain entry point.
|
|
178
|
+
*
|
|
179
|
+
* Three names refer to the *same* implementation:
|
|
180
|
+
* - `cas` — primary, brand-aligned, 3-letter (matches the
|
|
181
|
+
* muscle memory of FSS's `cas()` predecessor)
|
|
182
|
+
* - `css` — backronym "Cassida Single Style" — for those who
|
|
183
|
+
* prefer the CSS-native naming. Note: this collides
|
|
184
|
+
* with `css` from emotion / vanilla-extract; if you
|
|
185
|
+
* use those alongside Cassida, prefer `cas` or alias
|
|
186
|
+
* explicitly: `import { css as cs } from '@cassida/core'`.
|
|
187
|
+
* - `cassida` — long form for explicit code styles
|
|
188
|
+
*/
|
|
189
|
+
export declare const cas: CassBuilder;
|
|
190
|
+
export { cas as css };
|
|
191
|
+
export { cas as cassida };
|
|
192
|
+
export default cas;
|
|
193
|
+
export { canonicalSpec };
|
|
194
|
+
export type { CanonicalSpec, CanonicalMethodName, Op, Registry, } from '@cassida/compiler';
|
|
195
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { canonicalModifiers, canonicalSpec, compileOps, defaultRegistry, generatedPropertySpecs, } from '@cassida/compiler';
|
|
2
|
+
const cssToCamel = (prop) => prop.replace(/-([a-z])/g, (_match, c) => c.toUpperCase());
|
|
3
|
+
const camelToKebab = (s) => {
|
|
4
|
+
if (s.includes('-'))
|
|
5
|
+
return s;
|
|
6
|
+
return s.replace(/[A-Z]/g, (c) => `-${c.toLowerCase()}`);
|
|
7
|
+
};
|
|
8
|
+
function casCall(preset) {
|
|
9
|
+
const ops = [];
|
|
10
|
+
if (preset) {
|
|
11
|
+
for (const [key, val] of Object.entries(preset)) {
|
|
12
|
+
if (val === null || val === undefined)
|
|
13
|
+
continue;
|
|
14
|
+
ops.push({ method: key, args: [val] });
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return makeChain(defaultRegistry, ops, true);
|
|
18
|
+
}
|
|
19
|
+
function casUnsafe(preset) {
|
|
20
|
+
const ops = [];
|
|
21
|
+
for (const [key, val] of Object.entries(preset)) {
|
|
22
|
+
if (val === null || val === undefined)
|
|
23
|
+
continue;
|
|
24
|
+
ops.push({ property: camelToKebab(key), value: String(val) });
|
|
25
|
+
}
|
|
26
|
+
return makeChain(defaultRegistry, ops, true);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Cassida's chain entry point.
|
|
30
|
+
*
|
|
31
|
+
* Three names refer to the *same* implementation:
|
|
32
|
+
* - `cas` — primary, brand-aligned, 3-letter (matches the
|
|
33
|
+
* muscle memory of FSS's `cas()` predecessor)
|
|
34
|
+
* - `css` — backronym "Cassida Single Style" — for those who
|
|
35
|
+
* prefer the CSS-native naming. Note: this collides
|
|
36
|
+
* with `css` from emotion / vanilla-extract; if you
|
|
37
|
+
* use those alongside Cassida, prefer `cas` or alias
|
|
38
|
+
* explicitly: `import { css as cs } from '@cassida/core'`.
|
|
39
|
+
* - `cassida` — long form for explicit code styles
|
|
40
|
+
*/
|
|
41
|
+
export const cas = Object.assign(casCall, {
|
|
42
|
+
unsafe: casUnsafe,
|
|
43
|
+
});
|
|
44
|
+
export { cas as css };
|
|
45
|
+
export { cas as cassida };
|
|
46
|
+
export default cas;
|
|
47
|
+
function makeChain(registry, ops, isRoot) {
|
|
48
|
+
const chain = Object.create(null);
|
|
49
|
+
// Style methods. The runtime registry already merges hand-crafted
|
|
50
|
+
// and generated entries, so this single loop covers both sources —
|
|
51
|
+
// every standard CSS property gets a callable method on the chain.
|
|
52
|
+
for (const method of Object.keys(registry)) {
|
|
53
|
+
Object.defineProperty(chain, method, {
|
|
54
|
+
enumerable: false,
|
|
55
|
+
writable: false,
|
|
56
|
+
configurable: false,
|
|
57
|
+
value: (...args) => {
|
|
58
|
+
ops.push({ method, args });
|
|
59
|
+
return chain;
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
// Zero-arg modifiers (hover, focus, before, darkMode, ...).
|
|
64
|
+
for (const [name, scope] of Object.entries(canonicalModifiers)) {
|
|
65
|
+
Object.defineProperty(chain, name, {
|
|
66
|
+
enumerable: false,
|
|
67
|
+
writable: false,
|
|
68
|
+
configurable: false,
|
|
69
|
+
value: (cb) => {
|
|
70
|
+
const innerOps = [];
|
|
71
|
+
cb(makeChain(registry, innerOps, false));
|
|
72
|
+
ops.push({ scope, ops: innerOps });
|
|
73
|
+
return chain;
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
// Arg-taking modifiers.
|
|
78
|
+
Object.defineProperty(chain, 'media', {
|
|
79
|
+
enumerable: false,
|
|
80
|
+
writable: false,
|
|
81
|
+
configurable: false,
|
|
82
|
+
value: (query, cb) => {
|
|
83
|
+
const innerOps = [];
|
|
84
|
+
cb(makeChain(registry, innerOps, false));
|
|
85
|
+
const scope = { kind: 'media', query };
|
|
86
|
+
ops.push({ scope, ops: innerOps });
|
|
87
|
+
return chain;
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
Object.defineProperty(chain, 'on', {
|
|
91
|
+
enumerable: false,
|
|
92
|
+
writable: false,
|
|
93
|
+
configurable: false,
|
|
94
|
+
value: (selector, cb) => {
|
|
95
|
+
const innerOps = [];
|
|
96
|
+
cb(makeChain(registry, innerOps, false));
|
|
97
|
+
const scope = selector.trim().startsWith('@media')
|
|
98
|
+
? { kind: 'media', query: selector.replace(/^@media\s*/, '') }
|
|
99
|
+
: selector.startsWith(':') || selector.startsWith('::')
|
|
100
|
+
? { kind: 'pseudo', selector }
|
|
101
|
+
: { kind: 'raw', selector };
|
|
102
|
+
ops.push({ scope, ops: innerOps });
|
|
103
|
+
return chain;
|
|
104
|
+
},
|
|
105
|
+
});
|
|
106
|
+
// Escape hatch — direct CSS property write that bypasses the
|
|
107
|
+
// registry. Pairs with `cas.unsafe(preset)`. camelCase keys are
|
|
108
|
+
// converted to kebab-case so `set('paddingTop', '10px')` and
|
|
109
|
+
// `set('padding-top', '10px')` produce the same bag (and therefore
|
|
110
|
+
// the same className) — matching `paddingTop(10)` exactly when the
|
|
111
|
+
// value is unit-included.
|
|
112
|
+
Object.defineProperty(chain, 'set', {
|
|
113
|
+
enumerable: false,
|
|
114
|
+
writable: false,
|
|
115
|
+
configurable: false,
|
|
116
|
+
value: (key, value) => {
|
|
117
|
+
ops.push({ property: camelToKebab(key), value: String(value) });
|
|
118
|
+
return chain;
|
|
119
|
+
},
|
|
120
|
+
});
|
|
121
|
+
// Only the root chain exposes `style` to JSX spread. Inner chains
|
|
122
|
+
// accumulate ops for the outer; spreading them would leak the inner
|
|
123
|
+
// bag.
|
|
124
|
+
if (isRoot) {
|
|
125
|
+
Object.defineProperty(chain, 'style', {
|
|
126
|
+
enumerable: true,
|
|
127
|
+
configurable: false,
|
|
128
|
+
get() {
|
|
129
|
+
const { tree } = compileOps(ops, { registry });
|
|
130
|
+
const style = {};
|
|
131
|
+
for (const k of Object.keys(tree.bag)) {
|
|
132
|
+
style[cssToCamel(k)] = tree.bag[k];
|
|
133
|
+
}
|
|
134
|
+
return Object.freeze(style);
|
|
135
|
+
},
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
return chain;
|
|
139
|
+
}
|
|
140
|
+
export { canonicalSpec };
|
|
141
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@cassida/core",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Cassida runtime — cas() chain builder. In production this is replaced at build time; in dev / for dynamic chains it materializes inline style.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"csstype": "^3.1.3",
|
|
20
|
+
"@cassida/compiler": "0.1.0"
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"@types/node": "^22.9.0",
|
|
24
|
+
"typescript": "^5.6.3",
|
|
25
|
+
"vitest": "^2.1.4"
|
|
26
|
+
},
|
|
27
|
+
"repository": {
|
|
28
|
+
"type": "git",
|
|
29
|
+
"url": "git+https://github.com/pishio/cassida.git",
|
|
30
|
+
"directory": "packages/core"
|
|
31
|
+
},
|
|
32
|
+
"homepage": "https://github.com/pishio/cassida/tree/main/packages/core#readme",
|
|
33
|
+
"bugs": {
|
|
34
|
+
"url": "https://github.com/pishio/cassida/issues"
|
|
35
|
+
},
|
|
36
|
+
"author": "pishio",
|
|
37
|
+
"keywords": [
|
|
38
|
+
"cassida",
|
|
39
|
+
"css-in-js",
|
|
40
|
+
"compile-time",
|
|
41
|
+
"single-class",
|
|
42
|
+
"react"
|
|
43
|
+
],
|
|
44
|
+
"publishConfig": {
|
|
45
|
+
"access": "public"
|
|
46
|
+
},
|
|
47
|
+
"scripts": {
|
|
48
|
+
"build": "tsc -p tsconfig.json",
|
|
49
|
+
"test": "vitest run",
|
|
50
|
+
"typecheck": "tsc -p tsconfig.typecheck.json"
|
|
51
|
+
}
|
|
52
|
+
}
|