@invisra/printspec 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/README.md ADDED
@@ -0,0 +1,76 @@
1
+ # @invisra/printspec
2
+
3
+ TypeScript package for printspec JSON Schemas, offline validation, BOM helpers, browser form metadata helpers, CLI commands, deterministic bundle export, and starter OpenSCAD/CadQuery source generation.
4
+
5
+ **Status: v0.1.0 experimental.** The package is prepared for npm publication. If it is not yet published, install from the repository workspace instead of assuming registry availability.
6
+
7
+ ## Installation
8
+
9
+ ```sh
10
+ # From a repository checkout
11
+ npm install
12
+ npm --workspace @invisra/printspec run build
13
+
14
+ # Once published
15
+ npm install @invisra/printspec
16
+ ```
17
+
18
+ ## ESM-only API usage
19
+
20
+ This package is ESM-only (`"type": "module"`).
21
+
22
+ ```js
23
+ import { validatePrintSpec, generateOpenScad } from "@invisra/printspec";
24
+
25
+ const spec = {
26
+ printspecVersion: "0.1.0",
27
+ units: "mm",
28
+ part: {
29
+ type: "round_spacer",
30
+ label: "Smoke spacer",
31
+ parameters: { outerDiameter: 12, innerDiameter: 4, height: 8 }
32
+ }
33
+ };
34
+
35
+ const result = validatePrintSpec(spec);
36
+ console.log(result.valid, result.errors);
37
+
38
+ const generated = generateOpenScad(spec);
39
+ if (generated.supported) console.log(generated.code);
40
+ ```
41
+
42
+ ## CLI usage
43
+
44
+ ```sh
45
+ printspec --version
46
+ printspec validate examples/part-families/rounded-rectangular-plate.basic.json
47
+ printspec bom examples/projects/simple-enclosure-project.json --format markdown
48
+ printspec form-metadata rounded_rectangular_plate
49
+ printspec list-part-families
50
+ printspec to-openscad examples/part-families/round-spacer.basic.json --output round-spacer.scad
51
+ printspec to-cadquery examples/part-families/electronics-standoff.m3.json --output standoff.py
52
+ printspec bundle examples/part-families/rounded-rectangular-plate.basic.json --output bundle --overwrite
53
+ ```
54
+
55
+ ## Bundle example
56
+
57
+ ```js
58
+ import { createBundle, writeBundleToDirectory } from "@invisra/printspec";
59
+
60
+ const bundle = createBundle(spec, { includePartCad: true });
61
+ writeBundleToDirectory(bundle, "bundle", { overwrite: true });
62
+ ```
63
+
64
+ ## Package exports and bundled schemas
65
+
66
+ The package exports the main ESM API from `@invisra/printspec` and package schema files through `@invisra/printspec/schemas/*`. Schema files are bundled in the npm package under `schemas/`.
67
+
68
+ Validation resolves bundled schemas offline. It does not fetch hosted schema URLs during normal validation.
69
+
70
+ ## Hosted schema note
71
+
72
+ Hosted schemas at `https://schemas.invisra.ai/printspec/0.1.0/` are public references for documentation and external tools. They are not required for package validation.
73
+
74
+ ## Safety note
75
+
76
+ Generated OpenSCAD and CadQuery source is a starter artifact for review. This package does not export STL/STEP/3MF files and does not run CAD runtimes, slicers, supplier APIs, or purchasing automation. Do not use generated designs without appropriate engineering review.
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "@invisra/printspec",
3
+ "version": "0.1.0",
4
+ "description": "JSON schemas, validators, BOM helpers, CLI commands, and starter generators for practical parametric 3D-printable parts.",
5
+ "license": "Apache-2.0",
6
+ "author": "Invisra",
7
+ "type": "module",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/invisra/printspec.git",
11
+ "directory": "packages/typescript"
12
+ },
13
+ "homepage": "https://github.com/invisra/printspec#readme",
14
+ "bugs": {
15
+ "url": "https://github.com/invisra/printspec/issues"
16
+ },
17
+ "keywords": [
18
+ "3d-printing",
19
+ "cad",
20
+ "json-schema",
21
+ "openscad",
22
+ "cadquery",
23
+ "parametric",
24
+ "bom",
25
+ "stl",
26
+ "step",
27
+ "manufacturing"
28
+ ],
29
+ "sideEffects": false,
30
+ "main": "dist/index.js",
31
+ "types": "dist/index.d.ts",
32
+ "exports": {
33
+ ".": {
34
+ "types": "./dist/index.d.ts",
35
+ "import": "./dist/index.js"
36
+ },
37
+ "./schemas/*": "./schemas/*",
38
+ "./package.json": "./package.json"
39
+ },
40
+ "files": [
41
+ "dist",
42
+ "schemas",
43
+ "README.md"
44
+ ],
45
+ "scripts": {
46
+ "build": "tsc",
47
+ "test": "npm run build && node --test ../../tests/typescript/*.test.js",
48
+ "clean": "rm -rf dist"
49
+ },
50
+ "dependencies": {
51
+ "ajv": "^8.17.1",
52
+ "ajv-formats": "^3.0.1"
53
+ },
54
+ "devDependencies": {
55
+ "@types/node": "^22.10.2",
56
+ "typescript": "^5.7.2"
57
+ },
58
+ "bin": {
59
+ "printspec": "dist/cli.js"
60
+ }
61
+ }
@@ -0,0 +1,226 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://schemas.invisra.ai/printspec/0.1.0/cable-clip.schema.json",
4
+ "type": "object",
5
+ "required": [
6
+ "type",
7
+ "label",
8
+ "parameters"
9
+ ],
10
+ "properties": {
11
+ "type": {
12
+ "const": "cable_clip",
13
+ "title": "Part type",
14
+ "description": "Stable printspec part family identifier."
15
+ },
16
+ "label": {
17
+ "type": "string",
18
+ "minLength": 1,
19
+ "title": "Label",
20
+ "description": "Human-readable name for this part."
21
+ },
22
+ "description": {
23
+ "type": "string",
24
+ "title": "Description",
25
+ "description": "Optional human-readable notes for this part."
26
+ },
27
+ "parameters": {
28
+ "type": "object",
29
+ "required": [
30
+ "baseLength",
31
+ "baseWidth",
32
+ "baseThickness",
33
+ "clipWallThickness"
34
+ ],
35
+ "properties": {
36
+ "baseLength": {
37
+ "type": "number",
38
+ "exclusiveMinimum": 0,
39
+ "maximum": 10000,
40
+ "title": "Base length",
41
+ "description": "Base length in millimeters.",
42
+ "x-printspec-control": "number",
43
+ "x-printspec-unit": "mm",
44
+ "x-printspec-step": 0.1,
45
+ "x-printspec-priority": "primary"
46
+ },
47
+ "baseWidth": {
48
+ "type": "number",
49
+ "exclusiveMinimum": 0,
50
+ "maximum": 10000,
51
+ "title": "Base width",
52
+ "description": "Base width in millimeters.",
53
+ "x-printspec-control": "number",
54
+ "x-printspec-unit": "mm",
55
+ "x-printspec-step": 0.1,
56
+ "x-printspec-priority": "primary"
57
+ },
58
+ "baseThickness": {
59
+ "type": "number",
60
+ "exclusiveMinimum": 0,
61
+ "maximum": 10000,
62
+ "title": "Base thickness",
63
+ "description": "Base thickness in millimeters.",
64
+ "x-printspec-control": "number",
65
+ "x-printspec-unit": "mm",
66
+ "x-printspec-step": 0.1,
67
+ "x-printspec-priority": "primary"
68
+ },
69
+ "clipInnerDiameter": {
70
+ "type": "number",
71
+ "exclusiveMinimum": 0,
72
+ "maximum": 10000,
73
+ "title": "Clip inner diameter",
74
+ "description": "Clip inner diameter in millimeters.",
75
+ "x-printspec-control": "number",
76
+ "x-printspec-unit": "mm",
77
+ "x-printspec-step": 0.1,
78
+ "x-printspec-priority": "advanced"
79
+ },
80
+ "clipOpeningWidth": {
81
+ "type": "number",
82
+ "exclusiveMinimum": 0,
83
+ "maximum": 10000,
84
+ "title": "Clip opening width",
85
+ "description": "Clip opening width in millimeters.",
86
+ "x-printspec-control": "number",
87
+ "x-printspec-unit": "mm",
88
+ "x-printspec-step": 0.1,
89
+ "x-printspec-priority": "advanced"
90
+ },
91
+ "clipWallThickness": {
92
+ "type": "number",
93
+ "exclusiveMinimum": 0,
94
+ "maximum": 10000,
95
+ "title": "Clip wall thickness",
96
+ "description": "Clip wall thickness in millimeters.",
97
+ "x-printspec-control": "number",
98
+ "x-printspec-unit": "mm",
99
+ "x-printspec-step": 0.1,
100
+ "x-printspec-priority": "primary"
101
+ },
102
+ "holes": {
103
+ "type": "array",
104
+ "items": {
105
+ "$ref": "common.schema.json#/$defs/Hole"
106
+ },
107
+ "title": "Holes",
108
+ "description": "Optional hole features to include in the generated part.",
109
+ "x-printspec-control": "hole-list",
110
+ "x-printspec-priority": "advanced",
111
+ "default": []
112
+ },
113
+ "slots": {
114
+ "type": "array",
115
+ "items": {
116
+ "$ref": "common.schema.json#/$defs/Slot"
117
+ },
118
+ "title": "Slots",
119
+ "description": "Optional slot features to include in the generated part.",
120
+ "x-printspec-control": "slot-list",
121
+ "x-printspec-priority": "advanced",
122
+ "default": []
123
+ },
124
+ "chamfer": {
125
+ "$ref": "common.schema.json#/$defs/Chamfer",
126
+ "title": "Chamfer",
127
+ "description": "Optional chamfer edge finishing request.",
128
+ "x-printspec-control": "number",
129
+ "x-printspec-priority": "advanced"
130
+ },
131
+ "fillet": {
132
+ "$ref": "common.schema.json#/$defs/Fillet",
133
+ "title": "Fillet",
134
+ "description": "Optional fillet edge finishing request.",
135
+ "x-printspec-control": "number",
136
+ "x-printspec-priority": "advanced"
137
+ },
138
+ "cornerRadius": {
139
+ "type": "number",
140
+ "exclusiveMinimum": 0,
141
+ "maximum": 10000,
142
+ "title": "Corner radius",
143
+ "description": "Corner radius in millimeters.",
144
+ "x-printspec-control": "number",
145
+ "x-printspec-unit": "mm",
146
+ "x-printspec-step": 0.1,
147
+ "x-printspec-priority": "advanced",
148
+ "examples": [
149
+ 4
150
+ ]
151
+ },
152
+ "mountingHoles": {
153
+ "type": "array",
154
+ "items": {
155
+ "$ref": "common.schema.json#/$defs/Hole"
156
+ },
157
+ "title": "Mounting holes",
158
+ "description": "Optional hole features to include in the generated part.",
159
+ "x-printspec-control": "hole-list",
160
+ "x-printspec-priority": "advanced",
161
+ "default": []
162
+ }
163
+ },
164
+ "additionalProperties": false,
165
+ "anyOf": [
166
+ {
167
+ "required": [
168
+ "clipInnerDiameter"
169
+ ]
170
+ },
171
+ {
172
+ "required": [
173
+ "clipOpeningWidth"
174
+ ]
175
+ }
176
+ ],
177
+ "title": "Parameters",
178
+ "description": "Editable parameters for Cable Clip.",
179
+ "x-printspec-ui": {
180
+ "order": [
181
+ "baseLength",
182
+ "baseWidth",
183
+ "baseThickness",
184
+ "clipInnerDiameter",
185
+ "clipOpeningWidth",
186
+ "clipWallThickness",
187
+ "holes",
188
+ "slots",
189
+ "chamfer",
190
+ "fillet",
191
+ "cornerRadius",
192
+ "mountingHoles"
193
+ ],
194
+ "groups": [
195
+ {
196
+ "id": "parameters",
197
+ "title": "Parameters",
198
+ "fields": [
199
+ "baseLength",
200
+ "baseWidth",
201
+ "baseThickness",
202
+ "clipInnerDiameter",
203
+ "clipOpeningWidth",
204
+ "clipWallThickness",
205
+ "holes",
206
+ "slots",
207
+ "chamfer",
208
+ "fillet",
209
+ "cornerRadius",
210
+ "mountingHoles"
211
+ ]
212
+ }
213
+ ]
214
+ }
215
+ },
216
+ "hardware": {
217
+ "type": "array",
218
+ "items": {
219
+ "$ref": "common.schema.json#/$defs/HardwareItem"
220
+ }
221
+ }
222
+ },
223
+ "additionalProperties": false,
224
+ "title": "Cable Clip",
225
+ "description": "Mountable clip for holding a cable or hose."
226
+ }
@@ -0,0 +1,229 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://schemas.invisra.ai/printspec/0.1.0/cable-comb.schema.json",
4
+ "type": "object",
5
+ "required": [
6
+ "type",
7
+ "label",
8
+ "parameters"
9
+ ],
10
+ "properties": {
11
+ "type": {
12
+ "const": "cable_comb",
13
+ "title": "Part type",
14
+ "description": "Stable printspec part family identifier."
15
+ },
16
+ "label": {
17
+ "type": "string",
18
+ "minLength": 1,
19
+ "title": "Label",
20
+ "description": "Human-readable name for this part."
21
+ },
22
+ "description": {
23
+ "type": "string",
24
+ "title": "Description",
25
+ "description": "Optional human-readable notes for this part."
26
+ },
27
+ "parameters": {
28
+ "type": "object",
29
+ "required": [
30
+ "length",
31
+ "width",
32
+ "thickness",
33
+ "slotCount",
34
+ "slotWidth",
35
+ "slotSpacing",
36
+ "slotDepth"
37
+ ],
38
+ "properties": {
39
+ "length": {
40
+ "type": "number",
41
+ "exclusiveMinimum": 0,
42
+ "maximum": 10000,
43
+ "title": "Length",
44
+ "description": "Length in millimeters.",
45
+ "x-printspec-control": "number",
46
+ "x-printspec-unit": "mm",
47
+ "x-printspec-step": 0.1,
48
+ "x-printspec-priority": "primary",
49
+ "examples": [
50
+ 100
51
+ ]
52
+ },
53
+ "width": {
54
+ "type": "number",
55
+ "exclusiveMinimum": 0,
56
+ "maximum": 10000,
57
+ "title": "Width",
58
+ "description": "Width in millimeters.",
59
+ "x-printspec-control": "number",
60
+ "x-printspec-unit": "mm",
61
+ "x-printspec-step": 0.1,
62
+ "x-printspec-priority": "primary",
63
+ "examples": [
64
+ 50
65
+ ]
66
+ },
67
+ "thickness": {
68
+ "type": "number",
69
+ "exclusiveMinimum": 0,
70
+ "maximum": 10000,
71
+ "title": "Thickness",
72
+ "description": "Thickness in millimeters.",
73
+ "x-printspec-control": "number",
74
+ "x-printspec-unit": "mm",
75
+ "x-printspec-step": 0.1,
76
+ "x-printspec-priority": "primary",
77
+ "examples": [
78
+ 3
79
+ ]
80
+ },
81
+ "slotCount": {
82
+ "type": "integer",
83
+ "minimum": 1,
84
+ "maximum": 64,
85
+ "title": "Slot count",
86
+ "description": "Slot count for the part.",
87
+ "x-printspec-control": "integer",
88
+ "x-printspec-unit": "count",
89
+ "x-printspec-step": 1,
90
+ "x-printspec-priority": "primary",
91
+ "examples": [
92
+ 8
93
+ ]
94
+ },
95
+ "slotWidth": {
96
+ "type": "number",
97
+ "exclusiveMinimum": 0,
98
+ "maximum": 10000,
99
+ "title": "Slot width",
100
+ "description": "Slot width in millimeters.",
101
+ "x-printspec-control": "number",
102
+ "x-printspec-unit": "mm",
103
+ "x-printspec-step": 0.1,
104
+ "x-printspec-priority": "primary"
105
+ },
106
+ "slotSpacing": {
107
+ "type": "number",
108
+ "exclusiveMinimum": 0,
109
+ "maximum": 10000,
110
+ "title": "Slot spacing",
111
+ "description": "Slot spacing in millimeters.",
112
+ "x-printspec-control": "number",
113
+ "x-printspec-unit": "mm",
114
+ "x-printspec-step": 0.1,
115
+ "x-printspec-priority": "primary"
116
+ },
117
+ "slotDepth": {
118
+ "type": "number",
119
+ "exclusiveMinimum": 0,
120
+ "maximum": 10000,
121
+ "title": "Slot depth",
122
+ "description": "Slot depth in millimeters.",
123
+ "x-printspec-control": "number",
124
+ "x-printspec-unit": "mm",
125
+ "x-printspec-step": 0.1,
126
+ "x-printspec-priority": "primary"
127
+ },
128
+ "holes": {
129
+ "type": "array",
130
+ "items": {
131
+ "$ref": "common.schema.json#/$defs/Hole"
132
+ },
133
+ "title": "Holes",
134
+ "description": "Optional hole features to include in the generated part.",
135
+ "x-printspec-control": "hole-list",
136
+ "x-printspec-priority": "advanced",
137
+ "default": []
138
+ },
139
+ "slots": {
140
+ "type": "array",
141
+ "items": {
142
+ "$ref": "common.schema.json#/$defs/Slot"
143
+ },
144
+ "title": "Slots",
145
+ "description": "Optional slot features to include in the generated part.",
146
+ "x-printspec-control": "slot-list",
147
+ "x-printspec-priority": "advanced",
148
+ "default": []
149
+ },
150
+ "chamfer": {
151
+ "$ref": "common.schema.json#/$defs/Chamfer",
152
+ "title": "Chamfer",
153
+ "description": "Optional chamfer edge finishing request.",
154
+ "x-printspec-control": "number",
155
+ "x-printspec-priority": "advanced"
156
+ },
157
+ "fillet": {
158
+ "$ref": "common.schema.json#/$defs/Fillet",
159
+ "title": "Fillet",
160
+ "description": "Optional fillet edge finishing request.",
161
+ "x-printspec-control": "number",
162
+ "x-printspec-priority": "advanced"
163
+ },
164
+ "cornerRadius": {
165
+ "type": "number",
166
+ "exclusiveMinimum": 0,
167
+ "maximum": 10000,
168
+ "title": "Corner radius",
169
+ "description": "Corner radius in millimeters.",
170
+ "x-printspec-control": "number",
171
+ "x-printspec-unit": "mm",
172
+ "x-printspec-step": 0.1,
173
+ "x-printspec-priority": "advanced",
174
+ "examples": [
175
+ 4
176
+ ]
177
+ }
178
+ },
179
+ "additionalProperties": false,
180
+ "title": "Parameters",
181
+ "description": "Editable parameters for Cable Comb.",
182
+ "x-printspec-ui": {
183
+ "order": [
184
+ "length",
185
+ "width",
186
+ "thickness",
187
+ "slotCount",
188
+ "slotWidth",
189
+ "slotSpacing",
190
+ "slotDepth",
191
+ "holes",
192
+ "slots",
193
+ "chamfer",
194
+ "fillet",
195
+ "cornerRadius"
196
+ ],
197
+ "groups": [
198
+ {
199
+ "id": "parameters",
200
+ "title": "Parameters",
201
+ "fields": [
202
+ "length",
203
+ "width",
204
+ "thickness",
205
+ "slotCount",
206
+ "slotWidth",
207
+ "slotSpacing",
208
+ "slotDepth",
209
+ "holes",
210
+ "slots",
211
+ "chamfer",
212
+ "fillet",
213
+ "cornerRadius"
214
+ ]
215
+ }
216
+ ]
217
+ }
218
+ },
219
+ "hardware": {
220
+ "type": "array",
221
+ "items": {
222
+ "$ref": "common.schema.json#/$defs/HardwareItem"
223
+ }
224
+ }
225
+ },
226
+ "additionalProperties": false,
227
+ "title": "Cable Comb",
228
+ "description": "Comb-style cable organizer with repeated cable slots."
229
+ }