@pacp/spec 1.0.1 → 2.0.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 CHANGED
@@ -19,13 +19,10 @@ npm install @pacp/spec ajv ajv-formats
19
19
  ### Schema e profiles (sem dependências extras)
20
20
 
21
21
  ```typescript
22
- import { schema, profiles, profileIds, SPEC_VERSION } from '@pacp/spec';
22
+ import { schema, profiles, profileIds } from '@pacp/spec';
23
23
 
24
- // JSON Schema completo do PACP v1.0.0
25
- console.log(schema.$id); // "https://pacp.dev/spec/1.0.0/pacp.schema.json"
26
-
27
- // Versão da spec
28
- console.log(SPEC_VERSION); // "1.0.0"
24
+ // JSON Schema completo do PACP
25
+ console.log(schema.$id);
29
26
 
30
27
  // Extension profiles disponíveis
31
28
  console.log(profileIds); // ["moveis", "iluminacao", "pisos-revestimentos", "fiscal-br"]
@@ -40,7 +37,6 @@ console.log(profiles.moveis.title); // "PACP Profile: Moveis e Alta Decoracao"
40
37
  import { validate } from '@pacp/spec';
41
38
 
42
39
  const catalogDocument = {
43
- spec: '1.0.0',
44
40
  document_type: 'CATALOG',
45
41
  catalog: { id: 'meu_catalogo' },
46
42
  rulesets: [
@@ -80,9 +76,10 @@ import type {
80
76
  Dependency,
81
77
  Context,
82
78
  Option,
83
- ImageRef,
79
+ Image,
84
80
  Measure,
85
- DimensionsObj,
81
+ PhysicalDimensions,
82
+ LookupAxis,
86
83
  ValidationResult,
87
84
  } from '@pacp/spec';
88
85
 
@@ -96,7 +93,7 @@ const product: Product = {
96
93
  weight: { value: 45, unit: 'kg' },
97
94
  dimensions: { width: 160, height: 78, depth: 90, unit: 'cm' },
98
95
  options: [
99
- { id: 'opt_madeira', attributeId: 'material', value: 'CARVALHO' },
96
+ { id: 'opt_madeira', attribute_id: 'material', value: 'CARVALHO' },
100
97
  ],
101
98
  'x-finish': 'Natural envernizado',
102
99
  'x-warranty_months': 24,
@@ -122,11 +119,10 @@ const fiscal = require('@pacp/spec/profiles/fiscal-br.json');
122
119
 
123
120
  | Export | Descrição |
124
121
  |--------|-----------|
125
- | `schema` | JSON Schema completo do PACP v1.0.0 |
122
+ | `schema` | JSON Schema completo do PACP |
126
123
  | `profiles` | Objeto com todos os profiles oficiais |
127
124
  | `profileIds` | Array com IDs dos profiles: `moveis`, `iluminacao`, `pisos-revestimentos`, `fiscal-br` |
128
125
  | `validate()` | Função de validação (requer `ajv` + `ajv-formats`) |
129
- | `SPEC_VERSION` | Constante `"1.0.0"` |
130
126
  | Tipos TS | `CatalogDocument`, `ProductDocument`, `Product`, `Rule`, `Table`, etc. |
131
127
 
132
128
  ## Extension Profiles
@@ -140,7 +136,7 @@ const fiscal = require('@pacp/spec/profiles/fiscal-br.json');
140
136
 
141
137
  ## Links
142
138
 
143
- - [Spec v1.0.0](https://github.com/pacp-org/pacp/blob/main/spec/1.0.0/pacp.md)
139
+ - [Spec](https://github.com/pacp-org/pacp/blob/main/spec/latest/pacp.md)
144
140
  - [Guia de integração](https://github.com/pacp-org/pacp/blob/main/docs/integration-guide.md)
145
141
  - [Site](https://pacp-org.github.io/pacp/)
146
142
  - [GitHub](https://github.com/pacp-org/pacp)
package/dist/index.cjs CHANGED
@@ -20,7 +20,6 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var src_exports = {};
22
22
  __export(src_exports, {
23
- SPEC_VERSION: () => SPEC_VERSION,
24
23
  profileIds: () => profileIds,
25
24
  profiles: () => profiles,
26
25
  schema: () => schema,
@@ -119,12 +118,8 @@ function extractXFields(obj) {
119
118
  }
120
119
  return result;
121
120
  }
122
-
123
- // src/index.ts
124
- var SPEC_VERSION = "1.0.0";
125
121
  // Annotate the CommonJS export names for ESM import in node:
126
122
  0 && (module.exports = {
127
- SPEC_VERSION,
128
123
  profileIds,
129
124
  profiles,
130
125
  schema,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/schema.ts","../src/validate.ts"],"sourcesContent":["export { schema, profiles, profileIds } from \"./schema.js\";\r\nexport { validate } from \"./validate.js\";\r\nexport type {\r\n ScalarValue,\r\n ImageType,\r\n ImageRef,\r\n Measure,\r\n DimensionsObj,\r\n AttributeRef,\r\n AttributeValue,\r\n Option,\r\n LotPolicy,\r\n SalesUnit,\r\n Product,\r\n Predicate,\r\n Condition,\r\n Component,\r\n RuleOperation,\r\n Rule,\r\n Ruleset,\r\n Dimension,\r\n TableRow,\r\n Table,\r\n Dependency,\r\n Constraint,\r\n PriceList,\r\n Catalog,\r\n ProductRef,\r\n Context,\r\n Pricing,\r\n CatalogDocument,\r\n ProductDocument,\r\n PacpDocument,\r\n ProfileId,\r\n ValidationIssue,\r\n ValidationResult,\r\n} from \"./types.js\";\r\n\r\nexport const SPEC_VERSION = \"1.0.0\" as const;\r\n","import { readFileSync } from \"node:fs\";\r\nimport { join } from \"node:path\";\r\n\r\nfunction loadJson(relativePath: string): Record<string, unknown> {\r\n const fullPath = join(__dirname, relativePath);\r\n return JSON.parse(readFileSync(fullPath, \"utf8\"));\r\n}\r\n\r\nexport const schema = loadJson(\"./pacp.schema.json\") as Record<string, unknown>;\r\n\r\nexport const profiles = {\r\n moveis: loadJson(\"./profiles/moveis.schema.json\") as Record<string, unknown>,\r\n iluminacao: loadJson(\"./profiles/iluminacao.schema.json\") as Record<string, unknown>,\r\n \"pisos-revestimentos\": loadJson(\"./profiles/pisos-revestimentos.schema.json\") as Record<string, unknown>,\r\n \"fiscal-br\": loadJson(\"./profiles/fiscal-br.schema.json\") as Record<string, unknown>,\r\n} as const;\r\n\r\nexport type ProfileId = keyof typeof profiles;\r\n\r\nexport const profileIds = Object.keys(profiles) as ProfileId[];\r\n","import type { ValidationResult, ValidationIssue, PacpDocument } from \"./types.js\";\r\nimport { schema, profiles, type ProfileId } from \"./schema.js\";\r\n\r\nexport function validate(document: unknown): ValidationResult {\r\n let Ajv2020: typeof import(\"ajv/dist/2020\").default;\r\n let addFormats: typeof import(\"ajv-formats\").default;\r\n\r\n try {\r\n Ajv2020 = require(\"ajv/dist/2020\") as typeof import(\"ajv/dist/2020\").default;\r\n addFormats = require(\"ajv-formats\") as typeof import(\"ajv-formats\").default;\r\n } catch {\r\n throw new Error(\r\n 'Para usar validate(), instale ajv e ajv-formats: npm install ajv ajv-formats'\r\n );\r\n }\r\n\r\n const ajv = new Ajv2020({ allErrors: true, strict: false });\r\n addFormats(ajv);\r\n\r\n const issues: ValidationIssue[] = [];\r\n\r\n const validateSchema = ajv.compile(schema);\r\n const valid = validateSchema(document);\r\n\r\n if (!valid && validateSchema.errors) {\r\n for (const error of validateSchema.errors) {\r\n issues.push({\r\n code: \"SCHEMA\",\r\n path: error.instancePath || \"/\",\r\n message: error.message ?? \"Erro de validacao de schema\",\r\n });\r\n }\r\n }\r\n\r\n if (document && typeof document === \"object\" && !Array.isArray(document)) {\r\n const doc = document as Record<string, unknown>;\r\n const declaredProfiles = Array.isArray(doc.profiles) ? doc.profiles : [];\r\n\r\n for (const profileId of declaredProfiles) {\r\n if (typeof profileId !== \"string\") continue;\r\n\r\n const profileSchema = profiles[profileId as ProfileId];\r\n if (!profileSchema) {\r\n issues.push({\r\n code: \"UNKNOWN_PROFILE\",\r\n path: \"/profiles\",\r\n message: `Profile \"${profileId}\" nao e um profile oficial PACP`,\r\n });\r\n continue;\r\n }\r\n\r\n const products = extractProducts(doc);\r\n const validateProfile = ajv.compile(profileSchema);\r\n\r\n for (let i = 0; i < products.length; i++) {\r\n const xFields = extractXFields(products[i]);\r\n if (Object.keys(xFields).length === 0) continue;\r\n\r\n const profileValid = validateProfile(xFields);\r\n if (!profileValid && validateProfile.errors) {\r\n for (const error of validateProfile.errors) {\r\n issues.push({\r\n code: \"PROFILE_VALIDATION\",\r\n path: `products[${i}]${error.instancePath || \"/\"}`,\r\n message: `Profile \"${profileId}\": ${error.message ?? \"erro de validacao\"}`,\r\n });\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n return { valid: issues.length === 0, issues };\r\n}\r\n\r\nfunction extractProducts(doc: Record<string, unknown>): Record<string, unknown>[] {\r\n if (doc.document_type === \"PRODUCT\" && doc.product && typeof doc.product === \"object\") {\r\n return [doc.product as Record<string, unknown>];\r\n }\r\n return [];\r\n}\r\n\r\nfunction extractXFields(obj: Record<string, unknown>): Record<string, unknown> {\r\n const result: Record<string, unknown> = {};\r\n for (const [key, value] of Object.entries(obj)) {\r\n if (key.startsWith(\"x-\")) {\r\n result[key] = value;\r\n }\r\n }\r\n return result;\r\n}\r\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/schema.ts","../src/validate.ts"],"sourcesContent":["export { schema, profiles, profileIds } from \"./schema.js\";\r\nexport { validate } from \"./validate.js\";\r\nexport type {\r\n ScalarValue,\r\n ImageType,\r\n Image,\r\n Measure,\r\n PhysicalDimensions,\r\n AttributeRef,\r\n AttributeValue,\r\n Option,\r\n LotPolicy,\r\n SalesUnit,\r\n Product,\r\n Predicate,\r\n Condition,\r\n Component,\r\n RuleOperation,\r\n Rule,\r\n Ruleset,\r\n LookupAxis,\r\n TableRow,\r\n Table,\r\n Dependency,\r\n Constraint,\r\n PriceList,\r\n Catalog,\r\n ProductRef,\r\n Context,\r\n Pricing,\r\n CatalogDocument,\r\n ProductDocument,\r\n PacpDocument,\r\n ProfileId,\r\n ValidationIssue,\r\n ValidationResult,\r\n} from \"./types.js\";\r\n","import { readFileSync } from \"node:fs\";\r\nimport { join } from \"node:path\";\r\n\r\nfunction loadJson(relativePath: string): Record<string, unknown> {\r\n const fullPath = join(__dirname, relativePath);\r\n return JSON.parse(readFileSync(fullPath, \"utf8\"));\r\n}\r\n\r\nexport const schema = loadJson(\"./pacp.schema.json\") as Record<string, unknown>;\r\n\r\nexport const profiles = {\r\n moveis: loadJson(\"./profiles/moveis.schema.json\") as Record<string, unknown>,\r\n iluminacao: loadJson(\"./profiles/iluminacao.schema.json\") as Record<string, unknown>,\r\n \"pisos-revestimentos\": loadJson(\"./profiles/pisos-revestimentos.schema.json\") as Record<string, unknown>,\r\n \"fiscal-br\": loadJson(\"./profiles/fiscal-br.schema.json\") as Record<string, unknown>,\r\n} as const;\r\n\r\nexport type ProfileId = keyof typeof profiles;\r\n\r\nexport const profileIds = Object.keys(profiles) as ProfileId[];\r\n","import type { ValidationResult, ValidationIssue, PacpDocument } from \"./types.js\";\r\nimport { schema, profiles, type ProfileId } from \"./schema.js\";\r\n\r\nexport function validate(document: unknown): ValidationResult {\r\n let Ajv2020: typeof import(\"ajv/dist/2020\").default;\r\n let addFormats: typeof import(\"ajv-formats\").default;\r\n\r\n try {\r\n Ajv2020 = require(\"ajv/dist/2020\") as typeof import(\"ajv/dist/2020\").default;\r\n addFormats = require(\"ajv-formats\") as typeof import(\"ajv-formats\").default;\r\n } catch {\r\n throw new Error(\r\n 'Para usar validate(), instale ajv e ajv-formats: npm install ajv ajv-formats'\r\n );\r\n }\r\n\r\n const ajv = new Ajv2020({ allErrors: true, strict: false });\r\n addFormats(ajv);\r\n\r\n const issues: ValidationIssue[] = [];\r\n\r\n const validateSchema = ajv.compile(schema);\r\n const valid = validateSchema(document);\r\n\r\n if (!valid && validateSchema.errors) {\r\n for (const error of validateSchema.errors) {\r\n issues.push({\r\n code: \"SCHEMA\",\r\n path: error.instancePath || \"/\",\r\n message: error.message ?? \"Erro de validacao de schema\",\r\n });\r\n }\r\n }\r\n\r\n if (document && typeof document === \"object\" && !Array.isArray(document)) {\r\n const doc = document as Record<string, unknown>;\r\n const declaredProfiles = Array.isArray(doc.profiles) ? doc.profiles : [];\r\n\r\n for (const profileId of declaredProfiles) {\r\n if (typeof profileId !== \"string\") continue;\r\n\r\n const profileSchema = profiles[profileId as ProfileId];\r\n if (!profileSchema) {\r\n issues.push({\r\n code: \"UNKNOWN_PROFILE\",\r\n path: \"/profiles\",\r\n message: `Profile \"${profileId}\" nao e um profile oficial PACP`,\r\n });\r\n continue;\r\n }\r\n\r\n const products = extractProducts(doc);\r\n const validateProfile = ajv.compile(profileSchema);\r\n\r\n for (let i = 0; i < products.length; i++) {\r\n const xFields = extractXFields(products[i]);\r\n if (Object.keys(xFields).length === 0) continue;\r\n\r\n const profileValid = validateProfile(xFields);\r\n if (!profileValid && validateProfile.errors) {\r\n for (const error of validateProfile.errors) {\r\n issues.push({\r\n code: \"PROFILE_VALIDATION\",\r\n path: `products[${i}]${error.instancePath || \"/\"}`,\r\n message: `Profile \"${profileId}\": ${error.message ?? \"erro de validacao\"}`,\r\n });\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n return { valid: issues.length === 0, issues };\r\n}\r\n\r\nfunction extractProducts(doc: Record<string, unknown>): Record<string, unknown>[] {\r\n if (doc.document_type === \"PRODUCT\" && doc.product && typeof doc.product === \"object\") {\r\n return [doc.product as Record<string, unknown>];\r\n }\r\n return [];\r\n}\r\n\r\nfunction extractXFields(obj: Record<string, unknown>): Record<string, unknown> {\r\n const result: Record<string, unknown> = {};\r\n for (const [key, value] of Object.entries(obj)) {\r\n if (key.startsWith(\"x-\")) {\r\n result[key] = value;\r\n }\r\n }\r\n return result;\r\n}\r\n"],"mappings":"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","names":[]}
package/dist/index.d.cts CHANGED
@@ -2,7 +2,7 @@ export { profileIds, profiles, schema } from './schema.cjs';
2
2
 
3
3
  type ScalarValue = string | number | boolean;
4
4
  type ImageType = "MAIN" | "DETAIL" | "AMBIANCE" | "TECHNICAL" | "OTHER";
5
- interface ImageRef {
5
+ interface Image {
6
6
  url: string;
7
7
  label?: string;
8
8
  type?: ImageType;
@@ -11,7 +11,7 @@ interface Measure {
11
11
  value: number;
12
12
  unit: string;
13
13
  }
14
- interface DimensionsObj {
14
+ interface PhysicalDimensions {
15
15
  width?: number;
16
16
  height?: number;
17
17
  depth?: number;
@@ -22,27 +22,27 @@ interface AttributeRef {
22
22
  label?: string;
23
23
  }
24
24
  interface AttributeValue {
25
- attributeId: string;
25
+ attribute_id: string;
26
26
  value: ScalarValue;
27
27
  label?: string;
28
28
  }
29
29
  interface Option {
30
30
  id: string;
31
- attributeId: string;
31
+ attribute_id: string;
32
32
  value: ScalarValue;
33
33
  label?: string;
34
34
  }
35
35
  interface LotPolicy {
36
36
  required: boolean;
37
37
  source: "CONTEXT" | "ATTRIBUTE";
38
- contextKey?: string;
39
- attributeId?: string;
38
+ context_key?: string;
39
+ attribute_id?: string;
40
40
  }
41
41
  interface SalesUnit {
42
42
  requested_unit: string;
43
43
  sell_unit: string;
44
44
  quantity_per_sell_unit: number;
45
- rounding: "CEIL";
45
+ rounding: "CEIL" | "FLOOR" | "ROUND" | "HALF_UP";
46
46
  min_sell_units?: number;
47
47
  }
48
48
  interface Product {
@@ -56,16 +56,16 @@ interface Product {
56
56
  gtin?: string;
57
57
  base_price?: number;
58
58
  unit?: string;
59
- images?: ImageRef[];
59
+ images?: Image[];
60
60
  tags?: string[];
61
61
  weight?: Measure;
62
- dimensions?: DimensionsObj;
62
+ dimensions?: PhysicalDimensions;
63
63
  lot_policy?: LotPolicy;
64
64
  sales_unit?: SalesUnit;
65
65
  attributes?: AttributeRef[];
66
66
  attribute_values?: AttributeValue[];
67
67
  options: Option[];
68
- rulesetIds?: string[];
68
+ ruleset_ids?: string[];
69
69
  [key: `x-${string}`]: unknown;
70
70
  }
71
71
  interface Predicate {
@@ -81,8 +81,8 @@ interface Condition {
81
81
  interface Component {
82
82
  label?: string;
83
83
  value?: number;
84
- tableId?: string;
85
- optionId?: string;
84
+ table_id?: string;
85
+ option_id?: string;
86
86
  }
87
87
  type RuleOperation = "ADD" | "PERCENT_OF" | "OVERRIDE" | "LOOKUP" | "MAX_OF" | "MIN_OF" | "PICK" | "ROUND" | "CAP" | "FLOOR";
88
88
  interface Rule {
@@ -93,14 +93,14 @@ interface Rule {
93
93
  when?: Condition;
94
94
  value?: number;
95
95
  percent?: number;
96
- tableId?: string;
96
+ table_id?: string;
97
97
  components?: Component[];
98
98
  precision?: number;
99
99
  max?: number;
100
100
  min?: number;
101
101
  fallback?: number;
102
- optionId?: string;
103
- optionIds?: string[];
102
+ option_id?: string;
103
+ option_ids?: string[];
104
104
  [key: `x-${string}`]: unknown;
105
105
  }
106
106
  interface Ruleset {
@@ -109,11 +109,11 @@ interface Ruleset {
109
109
  rules: Rule[];
110
110
  [key: `x-${string}`]: unknown;
111
111
  }
112
- interface Dimension {
112
+ interface LookupAxis {
113
113
  key: string;
114
114
  source: "ATTRIBUTE" | "CONTEXT" | "LITERAL";
115
- attributeId?: string;
116
- contextKey?: string;
115
+ attribute_id?: string;
116
+ context_key?: string;
117
117
  literal?: ScalarValue;
118
118
  }
119
119
  interface TableRow {
@@ -123,21 +123,16 @@ interface TableRow {
123
123
  interface Table {
124
124
  id: string;
125
125
  type: "LOOKUP";
126
- dimensions: Dimension[];
126
+ dimensions: LookupAxis[];
127
127
  rows: TableRow[];
128
- keys?: (string | {
129
- optionId?: string;
130
- id?: string;
131
- name?: string;
132
- })[];
133
128
  }
134
129
  interface Dependency {
135
130
  id: string;
136
131
  type: "REQUIRES" | "IMPLIES" | "AVAILABLE_OPTIONS_WHEN";
137
- productId?: string;
138
- optionId?: string;
139
- requiresOptionIds?: string[];
140
- allowedOptionIds?: string[];
132
+ product_id?: string;
133
+ option_id?: string;
134
+ requires_option_ids?: string[];
135
+ allowed_option_ids?: string[];
141
136
  when?: Condition;
142
137
  }
143
138
  interface Constraint {
@@ -145,8 +140,8 @@ interface Constraint {
145
140
  type: "DENY";
146
141
  when: Condition;
147
142
  message: string;
148
- productId?: string;
149
- optionIds?: string[];
143
+ product_id?: string;
144
+ option_ids?: string[];
150
145
  }
151
146
  interface PriceList {
152
147
  id: string;
@@ -173,13 +168,12 @@ interface Context {
173
168
  lot_id?: string;
174
169
  requested_quantity?: number;
175
170
  requested_unit?: string;
176
- [key: `x-${string}`]: unknown;
171
+ [key: string]: ScalarValue | undefined;
177
172
  }
178
173
  interface Pricing {
179
174
  calculation_mode?: "CASCADE" | "TABLE_LOOKUP" | "OVERRIDE_BY_VARIANT" | "COST_PLUS";
180
175
  }
181
176
  interface CatalogDocument {
182
- spec: "1.0.0";
183
177
  document_type: "CATALOG";
184
178
  catalog: Catalog;
185
179
  rulesets: Ruleset[];
@@ -194,7 +188,6 @@ interface CatalogDocument {
194
188
  [key: `x-${string}`]: unknown;
195
189
  }
196
190
  interface ProductDocument {
197
- spec: "1.0.0";
198
191
  document_type: "PRODUCT";
199
192
  catalog_id: string;
200
193
  product: Product;
@@ -219,6 +212,4 @@ interface ValidationResult {
219
212
 
220
213
  declare function validate(document: unknown): ValidationResult;
221
214
 
222
- declare const SPEC_VERSION: "1.0.0";
223
-
224
- export { type AttributeRef, type AttributeValue, type Catalog, type CatalogDocument, type Component, type Condition, type Constraint, type Context, type Dependency, type Dimension, type DimensionsObj, type ImageRef, type ImageType, type LotPolicy, type Measure, type Option, type PacpDocument, type Predicate, type PriceList, type Pricing, type Product, type ProductDocument, type ProductRef, type ProfileId, type Rule, type RuleOperation, type Ruleset, SPEC_VERSION, type SalesUnit, type ScalarValue, type Table, type TableRow, type ValidationIssue, type ValidationResult, validate };
215
+ export { type AttributeRef, type AttributeValue, type Catalog, type CatalogDocument, type Component, type Condition, type Constraint, type Context, type Dependency, type Image, type ImageType, type LookupAxis, type LotPolicy, type Measure, type Option, type PacpDocument, type PhysicalDimensions, type Predicate, type PriceList, type Pricing, type Product, type ProductDocument, type ProductRef, type ProfileId, type Rule, type RuleOperation, type Ruleset, type SalesUnit, type ScalarValue, type Table, type TableRow, type ValidationIssue, type ValidationResult, validate };
package/dist/index.d.ts CHANGED
@@ -2,7 +2,7 @@ export { profileIds, profiles, schema } from './schema.js';
2
2
 
3
3
  type ScalarValue = string | number | boolean;
4
4
  type ImageType = "MAIN" | "DETAIL" | "AMBIANCE" | "TECHNICAL" | "OTHER";
5
- interface ImageRef {
5
+ interface Image {
6
6
  url: string;
7
7
  label?: string;
8
8
  type?: ImageType;
@@ -11,7 +11,7 @@ interface Measure {
11
11
  value: number;
12
12
  unit: string;
13
13
  }
14
- interface DimensionsObj {
14
+ interface PhysicalDimensions {
15
15
  width?: number;
16
16
  height?: number;
17
17
  depth?: number;
@@ -22,27 +22,27 @@ interface AttributeRef {
22
22
  label?: string;
23
23
  }
24
24
  interface AttributeValue {
25
- attributeId: string;
25
+ attribute_id: string;
26
26
  value: ScalarValue;
27
27
  label?: string;
28
28
  }
29
29
  interface Option {
30
30
  id: string;
31
- attributeId: string;
31
+ attribute_id: string;
32
32
  value: ScalarValue;
33
33
  label?: string;
34
34
  }
35
35
  interface LotPolicy {
36
36
  required: boolean;
37
37
  source: "CONTEXT" | "ATTRIBUTE";
38
- contextKey?: string;
39
- attributeId?: string;
38
+ context_key?: string;
39
+ attribute_id?: string;
40
40
  }
41
41
  interface SalesUnit {
42
42
  requested_unit: string;
43
43
  sell_unit: string;
44
44
  quantity_per_sell_unit: number;
45
- rounding: "CEIL";
45
+ rounding: "CEIL" | "FLOOR" | "ROUND" | "HALF_UP";
46
46
  min_sell_units?: number;
47
47
  }
48
48
  interface Product {
@@ -56,16 +56,16 @@ interface Product {
56
56
  gtin?: string;
57
57
  base_price?: number;
58
58
  unit?: string;
59
- images?: ImageRef[];
59
+ images?: Image[];
60
60
  tags?: string[];
61
61
  weight?: Measure;
62
- dimensions?: DimensionsObj;
62
+ dimensions?: PhysicalDimensions;
63
63
  lot_policy?: LotPolicy;
64
64
  sales_unit?: SalesUnit;
65
65
  attributes?: AttributeRef[];
66
66
  attribute_values?: AttributeValue[];
67
67
  options: Option[];
68
- rulesetIds?: string[];
68
+ ruleset_ids?: string[];
69
69
  [key: `x-${string}`]: unknown;
70
70
  }
71
71
  interface Predicate {
@@ -81,8 +81,8 @@ interface Condition {
81
81
  interface Component {
82
82
  label?: string;
83
83
  value?: number;
84
- tableId?: string;
85
- optionId?: string;
84
+ table_id?: string;
85
+ option_id?: string;
86
86
  }
87
87
  type RuleOperation = "ADD" | "PERCENT_OF" | "OVERRIDE" | "LOOKUP" | "MAX_OF" | "MIN_OF" | "PICK" | "ROUND" | "CAP" | "FLOOR";
88
88
  interface Rule {
@@ -93,14 +93,14 @@ interface Rule {
93
93
  when?: Condition;
94
94
  value?: number;
95
95
  percent?: number;
96
- tableId?: string;
96
+ table_id?: string;
97
97
  components?: Component[];
98
98
  precision?: number;
99
99
  max?: number;
100
100
  min?: number;
101
101
  fallback?: number;
102
- optionId?: string;
103
- optionIds?: string[];
102
+ option_id?: string;
103
+ option_ids?: string[];
104
104
  [key: `x-${string}`]: unknown;
105
105
  }
106
106
  interface Ruleset {
@@ -109,11 +109,11 @@ interface Ruleset {
109
109
  rules: Rule[];
110
110
  [key: `x-${string}`]: unknown;
111
111
  }
112
- interface Dimension {
112
+ interface LookupAxis {
113
113
  key: string;
114
114
  source: "ATTRIBUTE" | "CONTEXT" | "LITERAL";
115
- attributeId?: string;
116
- contextKey?: string;
115
+ attribute_id?: string;
116
+ context_key?: string;
117
117
  literal?: ScalarValue;
118
118
  }
119
119
  interface TableRow {
@@ -123,21 +123,16 @@ interface TableRow {
123
123
  interface Table {
124
124
  id: string;
125
125
  type: "LOOKUP";
126
- dimensions: Dimension[];
126
+ dimensions: LookupAxis[];
127
127
  rows: TableRow[];
128
- keys?: (string | {
129
- optionId?: string;
130
- id?: string;
131
- name?: string;
132
- })[];
133
128
  }
134
129
  interface Dependency {
135
130
  id: string;
136
131
  type: "REQUIRES" | "IMPLIES" | "AVAILABLE_OPTIONS_WHEN";
137
- productId?: string;
138
- optionId?: string;
139
- requiresOptionIds?: string[];
140
- allowedOptionIds?: string[];
132
+ product_id?: string;
133
+ option_id?: string;
134
+ requires_option_ids?: string[];
135
+ allowed_option_ids?: string[];
141
136
  when?: Condition;
142
137
  }
143
138
  interface Constraint {
@@ -145,8 +140,8 @@ interface Constraint {
145
140
  type: "DENY";
146
141
  when: Condition;
147
142
  message: string;
148
- productId?: string;
149
- optionIds?: string[];
143
+ product_id?: string;
144
+ option_ids?: string[];
150
145
  }
151
146
  interface PriceList {
152
147
  id: string;
@@ -173,13 +168,12 @@ interface Context {
173
168
  lot_id?: string;
174
169
  requested_quantity?: number;
175
170
  requested_unit?: string;
176
- [key: `x-${string}`]: unknown;
171
+ [key: string]: ScalarValue | undefined;
177
172
  }
178
173
  interface Pricing {
179
174
  calculation_mode?: "CASCADE" | "TABLE_LOOKUP" | "OVERRIDE_BY_VARIANT" | "COST_PLUS";
180
175
  }
181
176
  interface CatalogDocument {
182
- spec: "1.0.0";
183
177
  document_type: "CATALOG";
184
178
  catalog: Catalog;
185
179
  rulesets: Ruleset[];
@@ -194,7 +188,6 @@ interface CatalogDocument {
194
188
  [key: `x-${string}`]: unknown;
195
189
  }
196
190
  interface ProductDocument {
197
- spec: "1.0.0";
198
191
  document_type: "PRODUCT";
199
192
  catalog_id: string;
200
193
  product: Product;
@@ -219,6 +212,4 @@ interface ValidationResult {
219
212
 
220
213
  declare function validate(document: unknown): ValidationResult;
221
214
 
222
- declare const SPEC_VERSION: "1.0.0";
223
-
224
- export { type AttributeRef, type AttributeValue, type Catalog, type CatalogDocument, type Component, type Condition, type Constraint, type Context, type Dependency, type Dimension, type DimensionsObj, type ImageRef, type ImageType, type LotPolicy, type Measure, type Option, type PacpDocument, type Predicate, type PriceList, type Pricing, type Product, type ProductDocument, type ProductRef, type ProfileId, type Rule, type RuleOperation, type Ruleset, SPEC_VERSION, type SalesUnit, type ScalarValue, type Table, type TableRow, type ValidationIssue, type ValidationResult, validate };
215
+ export { type AttributeRef, type AttributeValue, type Catalog, type CatalogDocument, type Component, type Condition, type Constraint, type Context, type Dependency, type Image, type ImageType, type LookupAxis, type LotPolicy, type Measure, type Option, type PacpDocument, type PhysicalDimensions, type Predicate, type PriceList, type Pricing, type Product, type ProductDocument, type ProductRef, type ProfileId, type Rule, type RuleOperation, type Ruleset, type SalesUnit, type ScalarValue, type Table, type TableRow, type ValidationIssue, type ValidationResult, validate };
package/dist/index.js CHANGED
@@ -103,11 +103,7 @@ function extractXFields(obj) {
103
103
  }
104
104
  return result;
105
105
  }
106
-
107
- // src/index.ts
108
- var SPEC_VERSION = "1.0.0";
109
106
  export {
110
- SPEC_VERSION,
111
107
  profileIds,
112
108
  profiles,
113
109
  schema,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../node_modules/tsup/assets/esm_shims.js","../src/schema.ts","../src/validate.ts","../src/index.ts"],"sourcesContent":["// Shim globals in esm bundle\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","import { readFileSync } from \"node:fs\";\r\nimport { join } from \"node:path\";\r\n\r\nfunction loadJson(relativePath: string): Record<string, unknown> {\r\n const fullPath = join(__dirname, relativePath);\r\n return JSON.parse(readFileSync(fullPath, \"utf8\"));\r\n}\r\n\r\nexport const schema = loadJson(\"./pacp.schema.json\") as Record<string, unknown>;\r\n\r\nexport const profiles = {\r\n moveis: loadJson(\"./profiles/moveis.schema.json\") as Record<string, unknown>,\r\n iluminacao: loadJson(\"./profiles/iluminacao.schema.json\") as Record<string, unknown>,\r\n \"pisos-revestimentos\": loadJson(\"./profiles/pisos-revestimentos.schema.json\") as Record<string, unknown>,\r\n \"fiscal-br\": loadJson(\"./profiles/fiscal-br.schema.json\") as Record<string, unknown>,\r\n} as const;\r\n\r\nexport type ProfileId = keyof typeof profiles;\r\n\r\nexport const profileIds = Object.keys(profiles) as ProfileId[];\r\n","import type { ValidationResult, ValidationIssue, PacpDocument } from \"./types.js\";\r\nimport { schema, profiles, type ProfileId } from \"./schema.js\";\r\n\r\nexport function validate(document: unknown): ValidationResult {\r\n let Ajv2020: typeof import(\"ajv/dist/2020\").default;\r\n let addFormats: typeof import(\"ajv-formats\").default;\r\n\r\n try {\r\n Ajv2020 = require(\"ajv/dist/2020\") as typeof import(\"ajv/dist/2020\").default;\r\n addFormats = require(\"ajv-formats\") as typeof import(\"ajv-formats\").default;\r\n } catch {\r\n throw new Error(\r\n 'Para usar validate(), instale ajv e ajv-formats: npm install ajv ajv-formats'\r\n );\r\n }\r\n\r\n const ajv = new Ajv2020({ allErrors: true, strict: false });\r\n addFormats(ajv);\r\n\r\n const issues: ValidationIssue[] = [];\r\n\r\n const validateSchema = ajv.compile(schema);\r\n const valid = validateSchema(document);\r\n\r\n if (!valid && validateSchema.errors) {\r\n for (const error of validateSchema.errors) {\r\n issues.push({\r\n code: \"SCHEMA\",\r\n path: error.instancePath || \"/\",\r\n message: error.message ?? \"Erro de validacao de schema\",\r\n });\r\n }\r\n }\r\n\r\n if (document && typeof document === \"object\" && !Array.isArray(document)) {\r\n const doc = document as Record<string, unknown>;\r\n const declaredProfiles = Array.isArray(doc.profiles) ? doc.profiles : [];\r\n\r\n for (const profileId of declaredProfiles) {\r\n if (typeof profileId !== \"string\") continue;\r\n\r\n const profileSchema = profiles[profileId as ProfileId];\r\n if (!profileSchema) {\r\n issues.push({\r\n code: \"UNKNOWN_PROFILE\",\r\n path: \"/profiles\",\r\n message: `Profile \"${profileId}\" nao e um profile oficial PACP`,\r\n });\r\n continue;\r\n }\r\n\r\n const products = extractProducts(doc);\r\n const validateProfile = ajv.compile(profileSchema);\r\n\r\n for (let i = 0; i < products.length; i++) {\r\n const xFields = extractXFields(products[i]);\r\n if (Object.keys(xFields).length === 0) continue;\r\n\r\n const profileValid = validateProfile(xFields);\r\n if (!profileValid && validateProfile.errors) {\r\n for (const error of validateProfile.errors) {\r\n issues.push({\r\n code: \"PROFILE_VALIDATION\",\r\n path: `products[${i}]${error.instancePath || \"/\"}`,\r\n message: `Profile \"${profileId}\": ${error.message ?? \"erro de validacao\"}`,\r\n });\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n return { valid: issues.length === 0, issues };\r\n}\r\n\r\nfunction extractProducts(doc: Record<string, unknown>): Record<string, unknown>[] {\r\n if (doc.document_type === \"PRODUCT\" && doc.product && typeof doc.product === \"object\") {\r\n return [doc.product as Record<string, unknown>];\r\n }\r\n return [];\r\n}\r\n\r\nfunction extractXFields(obj: Record<string, unknown>): Record<string, unknown> {\r\n const result: Record<string, unknown> = {};\r\n for (const [key, value] of Object.entries(obj)) {\r\n if (key.startsWith(\"x-\")) {\r\n result[key] = value;\r\n }\r\n }\r\n return result;\r\n}\r\n","export { schema, profiles, profileIds } from \"./schema.js\";\r\nexport { validate } from \"./validate.js\";\r\nexport type {\r\n ScalarValue,\r\n ImageType,\r\n ImageRef,\r\n Measure,\r\n DimensionsObj,\r\n AttributeRef,\r\n AttributeValue,\r\n Option,\r\n LotPolicy,\r\n SalesUnit,\r\n Product,\r\n Predicate,\r\n Condition,\r\n Component,\r\n RuleOperation,\r\n Rule,\r\n Ruleset,\r\n Dimension,\r\n TableRow,\r\n Table,\r\n Dependency,\r\n Constraint,\r\n PriceList,\r\n Catalog,\r\n ProductRef,\r\n Context,\r\n Pricing,\r\n CatalogDocument,\r\n ProductDocument,\r\n PacpDocument,\r\n ProfileId,\r\n ValidationIssue,\r\n ValidationResult,\r\n} from \"./types.js\";\r\n\r\nexport const SPEC_VERSION = \"1.0.0\" as const;\r\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../node_modules/tsup/assets/esm_shims.js","../src/schema.ts","../src/validate.ts"],"sourcesContent":["// Shim globals in esm bundle\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","import { readFileSync } from \"node:fs\";\r\nimport { join } from \"node:path\";\r\n\r\nfunction loadJson(relativePath: string): Record<string, unknown> {\r\n const fullPath = join(__dirname, relativePath);\r\n return JSON.parse(readFileSync(fullPath, \"utf8\"));\r\n}\r\n\r\nexport const schema = loadJson(\"./pacp.schema.json\") as Record<string, unknown>;\r\n\r\nexport const profiles = {\r\n moveis: loadJson(\"./profiles/moveis.schema.json\") as Record<string, unknown>,\r\n iluminacao: loadJson(\"./profiles/iluminacao.schema.json\") as Record<string, unknown>,\r\n \"pisos-revestimentos\": loadJson(\"./profiles/pisos-revestimentos.schema.json\") as Record<string, unknown>,\r\n \"fiscal-br\": loadJson(\"./profiles/fiscal-br.schema.json\") as Record<string, unknown>,\r\n} as const;\r\n\r\nexport type ProfileId = keyof typeof profiles;\r\n\r\nexport const profileIds = Object.keys(profiles) as ProfileId[];\r\n","import type { ValidationResult, ValidationIssue, PacpDocument } from \"./types.js\";\r\nimport { schema, profiles, type ProfileId } from \"./schema.js\";\r\n\r\nexport function validate(document: unknown): ValidationResult {\r\n let Ajv2020: typeof import(\"ajv/dist/2020\").default;\r\n let addFormats: typeof import(\"ajv-formats\").default;\r\n\r\n try {\r\n Ajv2020 = require(\"ajv/dist/2020\") as typeof import(\"ajv/dist/2020\").default;\r\n addFormats = require(\"ajv-formats\") as typeof import(\"ajv-formats\").default;\r\n } catch {\r\n throw new Error(\r\n 'Para usar validate(), instale ajv e ajv-formats: npm install ajv ajv-formats'\r\n );\r\n }\r\n\r\n const ajv = new Ajv2020({ allErrors: true, strict: false });\r\n addFormats(ajv);\r\n\r\n const issues: ValidationIssue[] = [];\r\n\r\n const validateSchema = ajv.compile(schema);\r\n const valid = validateSchema(document);\r\n\r\n if (!valid && validateSchema.errors) {\r\n for (const error of validateSchema.errors) {\r\n issues.push({\r\n code: \"SCHEMA\",\r\n path: error.instancePath || \"/\",\r\n message: error.message ?? \"Erro de validacao de schema\",\r\n });\r\n }\r\n }\r\n\r\n if (document && typeof document === \"object\" && !Array.isArray(document)) {\r\n const doc = document as Record<string, unknown>;\r\n const declaredProfiles = Array.isArray(doc.profiles) ? doc.profiles : [];\r\n\r\n for (const profileId of declaredProfiles) {\r\n if (typeof profileId !== \"string\") continue;\r\n\r\n const profileSchema = profiles[profileId as ProfileId];\r\n if (!profileSchema) {\r\n issues.push({\r\n code: \"UNKNOWN_PROFILE\",\r\n path: \"/profiles\",\r\n message: `Profile \"${profileId}\" nao e um profile oficial PACP`,\r\n });\r\n continue;\r\n }\r\n\r\n const products = extractProducts(doc);\r\n const validateProfile = ajv.compile(profileSchema);\r\n\r\n for (let i = 0; i < products.length; i++) {\r\n const xFields = extractXFields(products[i]);\r\n if (Object.keys(xFields).length === 0) continue;\r\n\r\n const profileValid = validateProfile(xFields);\r\n if (!profileValid && validateProfile.errors) {\r\n for (const error of validateProfile.errors) {\r\n issues.push({\r\n code: \"PROFILE_VALIDATION\",\r\n path: `products[${i}]${error.instancePath || \"/\"}`,\r\n message: `Profile \"${profileId}\": ${error.message ?? \"erro de validacao\"}`,\r\n });\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n return { valid: issues.length === 0, issues };\r\n}\r\n\r\nfunction extractProducts(doc: Record<string, unknown>): Record<string, unknown>[] {\r\n if (doc.document_type === \"PRODUCT\" && doc.product && typeof doc.product === \"object\") {\r\n return [doc.product as Record<string, unknown>];\r\n }\r\n return [];\r\n}\r\n\r\nfunction extractXFields(obj: Record<string, unknown>): Record<string, unknown> {\r\n const result: Record<string, unknown> = {};\r\n for (const [key, value] of Object.entries(obj)) {\r\n if (key.startsWith(\"x-\")) {\r\n result[key] = value;\r\n }\r\n }\r\n return result;\r\n}\r\n"],"mappings":"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","names":[]}